#include "experimentrunui.h"
#include "ui_experimentrunui.h"

ExperimentRunUi::ExperimentRunUi(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::ExperimentRunUi)
{
    ui->setupUi(this);

    /* 初始化 */
    procedureStepCount = 0;
    this->runFlag = true;
    this->currentProcedureStepCount = 1;
    this->currentCycling = 1;
    this->setSize = 0;
    this->totalCycling = 0;
    pauseDialog = new pause();
    pauseDialog->setWindowModality(Qt::ApplicationModal);
    procedureService = new ProcedureService();
    expStartRunningTimer = new QTimer();
    runThread = new QThread();
    comboboxEdit = new QLineEdit();
    cusMsg = new CustomMessageBox();
    runningTimer = new QTimer();

    /* 下拉框样式生效 */
    ui->legendSelector->setView(new QListView());

    /* 表格过滤 */
    menu = new QMenu();
    action_1 = new QAction(tr("&样本名称"));
    action_3 = new QAction(tr("&靶基因"));
    action_2 = new QAction(tr("&样本颜色"));
    action_1->setCheckable(true);
    action_3->setCheckable(true);
    action_2->setCheckable(true);
    action_1->setChecked(true);
    action_3->setChecked(true);
    action_2->setChecked(true);
    menu->addAction(action_1);
    menu->addAction(action_3);
    menu->addAction(action_2);
    /* QMenu样式 */
    menu->setStyleSheet("QMenu::item{"
                        "width: 107px;"
                        "font-size: 20px;"
                        "font-family: 'Alibaba PuHuiTi';"
                        "padding: 5px;"
                        "}"
                        "QMenu::item::selected {"
                        "color: #000;"
                        "border: none;"
                        "background: rgba(75, 154, 250, 0.2);"
                        "}");

    ui->toolButton->setMenu(menu);

    /* 设置QLineEdit样式 */
    comboboxEdit->setStyleSheet("QLineEdit{"
                                "font-size: 18px;"
                                "font-family: 'Alibaba PuHuiTi';"
                                "background: transparent;"
                                "}");
    /* 只读模式 */
    comboboxEdit->setReadOnly(true);

    /* 将QTimer移到线程中 */
    expStartRunningTimer->moveToThread(runThread);


    /* 初始化横轴大小 */
    this->xAxisMaximum = 0;
    this->yAxisMaximum = 8000;
    this->xSeries = -1;

    /* 图例初始化 */
    // 曲线：默认都可见
    this->cy5Visible = true;
    this->famVisible = true;
    this->vicVisible = true;
    this->roxVisible = true;
    // 初始化曲线的图例暂存列表：和曲线图例一样，全为true
    //    this->lineVisibleList = {{"1", true}, {"2", true}, {"3", true}, {"4", true}};
    this->lineVisibleList.insert("1", true);
    this->lineVisibleList.insert("2", true);
    this->lineVisibleList.insert("3", true);
    this->lineVisibleList.insert("4", true);

    /* 表格不可编辑 */
    ui->expRunTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
    /* 隐藏恢复按钮 */
    ui->runningRestore->hide();
    /* 隐藏错误窗口 */
    ui->errorWidget->hide();
    /* 按钮失效 */
    ui->stopBtn->setEnabled(false);
    ui->pauseOrContinueBtn->setEnabled(false);

    /* 设置设备列表的QLineEdit */
    ui->runningDevice->setLineEdit(comboboxEdit);

    /* 错误滚动条样式 */
    ui->errMsg->horizontalScrollBar()->setStyleSheet("QScrollBar:horizontal { height: 10px; }");

    ui->expRunTable->setMouseTracking(true);

    /*
     * 设置QTableWidget
      * 设置行高为48
    */
    // 表格自适应宽度
    ui->expRunTable->setVerticalHeaderLabels(QStringList() << "A" << "B" << "C" << "D" << "E" << "F" << "G" << "H");
    ui->expRunTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    ui->expRunTable->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    ui->expRunTable->setVerticalHeaderLabels(QStringList() << "A" << "B" << "C" << "D" << "E" << "F" << "G" << "H");
    ui->expRunTable->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    ui->expRunTable->verticalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    ui->expRunTable->horizontalHeader()->setDefaultAlignment(Qt::AlignCenter);
    ui->expRunTable->verticalHeader()->setDefaultAlignment(Qt::AlignCenter);
    ui->expRunTable->horizontalHeader()->setStyleSheet("QHeaderView::section{border:1px solid #000;border-top:none;border-left:none;height:32px;background:transparent;font-family:\"Alibaba PuHuiTi\";text-align:center;}");
    ui->expRunTable->verticalHeader()->setStyleSheet("QHeaderView::section{border:1px solid #000;border-top:none;border-left:none;width:23px;background:transparent;font-family:\"Alibaba PuHuiTi\";text-align:center;}");

    /* 绘制图表 */
    createLineChart(); // 创建曲线图
    createBarChart(); // 创建柱状图

    connect(ui->expRunTable,SIGNAL(entered(QModelIndex)),this,SLOT(ShowTooltip(QModelIndex)));

    /* 点击右扩展按钮 */
    connect(ui->runningRightExpending, &QPushButton::clicked, this, [=](){
        ui->expRunCurve->hide();
        ui->expTable->show();
        ui->runningRestore->show();
        ui->runningRightExpending->hide();
        ui->runningLeftExpending->show();
    });

    /* 点击左扩展按钮 */
    connect(ui->runningLeftExpending, &QPushButton::clicked, this, [=](){
        ui->expRunCurve->show();
        ui->expTable->hide();
        ui->runningRestore->show();
        ui->runningRightExpending->show();
        ui->runningLeftExpending->hide();
        ui->lineGraphicsView->update(); // 曲线更新，以免出现问题
        ui->barGraphicsView->update(); // 柱状图更新，以免出现问题
    });

    /* 点击还原按钮 */
    connect(ui->runningRestore, &QPushButton::clicked, this, [=](){
        ui->expRunCurve->show();
        ui->expTable->show();
        ui->runningRestore->hide();
        ui->runningRightExpending->show();
        ui->runningLeftExpending->show();
        ui->lineGraphicsView->update(); // 曲线更新，以免出现问题
        ui->barGraphicsView->update(); // 柱状图更新，以免出现问题
    });

    /* 点击启动按钮后显示运行状态 */
    connect(ui->startBtn, &QPushButton::clicked, this, &ExperimentRunUi::expStartRunning);

    /* 点击停止按钮后显示停止状态 */
    connect(ui->stopBtn, &QPushButton::clicked, this, &ExperimentRunUi::expStopRunning, Qt::QueuedConnection);

    /* 点击暂停/继续按钮，根据当前状态进行暂停或继续操作 */
    connect(ui->pauseOrContinueBtn, &QPushButton::clicked, this, &ExperimentRunUi::expPauseRunning, Qt::QueuedConnection);


    /* 实验暂停时事件 */
    connect(pauseDialog, &pause::sendPauseTemperature, this, [=](QString pauseTemp){
        ui->pauseOrContinueBtn->setText("继续");
        ui->pauseOrContinueBtn->setStyleSheet(
                    "font-family: 'Alibaba PuHuiTi';"
                    "color: #fff;"
                    "font-size: 18px;"
                    "font-weight: bold;"
                    "border-radius: 8px;"
                    "background-color: rgb(255, 170, 0);");

        ui->expRunStateLabel->setText("暂停中");
        ui->expRunStateLabel->setStyleSheet("QLabel {color:rgb(255, 170, 0);font-size:16px;font-family: \"Alibaba PuHuiTi\";}");
        this->runFlag = false;
        /* 获取暂停时温度 */
        pauseTemperature = pauseTemp;

        LOG << "pauseTemperature" << pauseTemperature;

        /* 初始化 */
        cDevS.instructionsService->ziJianData.clear();
        /* 判断是否连接 */
        if(!cDevS.instructionsService->m_socketClient->isConnected()){
            cDevS.instructionsService->establishConnection(cDevS.dev.ip, cDevS.dev.port.toInt());
        }
        /* 发送暂停时温度 */
        cDevS.instructionsService->sendStop(cDevS.dev.id, id, pauseTemperature);

        /* 发送信号：获取并渲染指令 */
        emit ExperimentRunUi::sigRenderZhiLingInfo();

        this->sleep(EXPERIMENT_RUNNING_SLEEP_TIME);
        /* 发送信号：获取并渲染指令 */
        emit ExperimentRunUi::sigRenderZhiLingInfo();
        /* 获取暂停时数据 */
        /* 不为空 */
        if(cDevS.instructionsService->ziJianData.size() != 0)
        {
            /* 关闭链接 */
            if(cDevS.instructionsService->m_socketClient->isConnected()){
                cDevS.instructionsService->m_socketClient->closeSocket();
            }
            /* 初始化 */
            cDevS.instructionsService->ziJianData.clear();
            /* 停止计时器 */
            this->runningTimer->stop();
            /* 将Tab状态颜色改变 */
            emit ExperimentRunUi::sigShowRunningStatus("暂停");
        }
        /* 数据为空 */
        else {
            /* 判断是否连接 */
            if(!cDevS.instructionsService->m_socketClient->isConnected()){
                cDevS.instructionsService->establishConnection(cDevS.dev.ip, cDevS.dev.port.toInt());
            }
            /* 发送暂停时温度 */
            cDevS.instructionsService->sendStop(cDevS.dev.id, id, pauseTemperature);
            /* 发送信号：获取并渲染指令 */
            emit ExperimentRunUi::sigRenderZhiLingInfo();

            this->sleep(EXPERIMENT_RUNNING_SLEEP_TIME);
            /* 发送信号：获取并渲染指令 */
            emit ExperimentRunUi::sigRenderZhiLingInfo();
            /* 获取暂停时数据 */
            if(cDevS.instructionsService->ziJianData.size() != 0){
                /* 关闭链接 */
                if(cDevS.instructionsService->m_socketClient->isConnected()){
                    cDevS.instructionsService->m_socketClient->closeSocket();
                }
                /* 初始化 */
                cDevS.instructionsService->ziJianData.clear();
                /* 停止计时器 */
                this->runningTimer->stop();
                /* 将Tab状态颜色改变 */
                emit ExperimentRunUi::sigShowRunningStatus("暂停");
            }
            /* 二次判空 */
            else {
                /* 显示样式 */
                emit ExperimentRunUi::sigIsEmptyStyle("暂停回传数据为空");
                /* 渲染到ui上 */
                ui->textEdit_mistake->append("暂停回传数据为空");
                /* 初始化 */
                cDevS.instructionsService->ziJianData.clear();
            }
        }
        /* 停止线程 */
        this->runThread->quit();
    });

    /* 不暂停事件 */
    connect(pauseDialog, &pause::dontPause, this, [=](){
        LOG << "dontPause<<<<<<<<<<<";
        this->runFlag = true;
    });

    /* 错误窗口关闭函数 */
    connect(ui->closeErrWidget, &QPushButton::clicked, this, [=](){
        ui->errorWidget->hide();
    });

    /* 线程唤醒定时器 */
    connect(runThread, SIGNAL(started()), expStartRunningTimer, SLOT(start()));

    /* 线程结束定时器 */
    connect(runThread, SIGNAL(finished()), expStartRunningTimer, SLOT(stop()));

    /* 绑定定时器 */
    connect(expStartRunningTimer, &QTimer::timeout, this, &ExperimentRunUi::expRunningTimerCallback, Qt::DirectConnection);

    /* 绑定函数渲染页面：刚进入循环时，界面样式设置 */
    connect(this, &ExperimentRunUi::sigInitStyle, this, &ExperimentRunUi::callbackInitStyle, Qt::QueuedConnection);

    /* 绑定函数渲染页面：回传信息为空时，界面样式设置 */
    connect(this, &ExperimentRunUi::sigIsEmptyStyle, this, &ExperimentRunUi::callbackIsEmptyStyle, Qt::QueuedConnection);

    /* 绑定函数渲染页面：回传信息为故障时，界面样式设置 */
    connect(this, &ExperimentRunUi::sigIsErrorStyle, this, &ExperimentRunUi::callbackIsErrorStyle, Qt::QueuedConnection);

    /* 绑定函数渲染页面：回传信息为成功时，界面样式设置 */
    connect(this, &ExperimentRunUi::sigIsSuccessStyle, this, &ExperimentRunUi::callbackIsSuccessStyle, Qt::QueuedConnection);

    /* 绑定函数渲染页面：回传温度时，界面样式设置 */
    connect(this, &ExperimentRunUi::sigIsTempStyle, this, &ExperimentRunUi::callbackIsTempStyle, Qt::QueuedConnection);

    /* 绑定函数渲染页面：回传数据，减时间和增加步骤/阶段/循环数 */
    connect(this, &ExperimentRunUi::sigMinusTime, this, &ExperimentRunUi::callbackMinusTime, Qt::QueuedConnection);

    /* 12.19改 绑定温度数据发送和接收 */
    connect(this, &ExperimentRunUi::sigGetWenduData, this, &ExperimentRunUi::callbackGetWenduData, Qt::BlockingQueuedConnection);

    /* 12.19改 绑定荧光数据的发送和接收 */
    connect(this, &ExperimentRunUi::sigGetYingGuangData, this, &ExperimentRunUi::callbackGetYingGuangData, Qt::BlockingQueuedConnection);

    /* 12.19改 绑定故障数据的发送和接收 */
    connect(this, &ExperimentRunUi::sigGetGuzhangData, this, &ExperimentRunUi::callbackGetGuzhangData, Qt::BlockingQueuedConnection);

    /* 绑定Socket关闭信号 */
    connect(this, &ExperimentRunUi::sigCloseDeviceSocket, this, &ExperimentRunUi::callbackCloseDeviceSocket, Qt::QueuedConnection);

    /* 接收扩增回传信息（减时间所用的温度和时间） */
    connect(this, &ExperimentRunUi::sigGetFinishedProcedureTime, this, &ExperimentRunUi::callbackGetFinishedProcedureTime, Qt::QueuedConnection);

    /* 渲染指令信息 */
    connect(this, &ExperimentRunUi::sigRenderZhiLingInfo, this, &ExperimentRunUi::callbackRenderNotParseZhilingInfo);

    /* 渲染阶段名称 */
    connect(this, &ExperimentRunUi::sigRenderStage, this, &ExperimentRunUi::callbackRenderStage);

    /* 获取当实验结束回传0时 */
    connect(this, &ExperimentRunUi::sigGetZeroSuccess, this, &ExperimentRunUi::callbackGetZeroSuccess);

    /* 运行时间计时器 */
    connect(runningTimer, &QTimer::timeout, this, &ExperimentRunUi::runningTimerCallback);

    /* 图例控制下拉框 */
    connect(ui->legendSelector, &QComboBox::currentTextChanged, this, [=](){
        this->colorControlFunction(); // 颜色控制器函数
        // 触发图例变换函数
        this->renderLegendStyle();
    });

    /* 上一步按钮 */
    connect(ui->previousBtn, &QPushButton::clicked, this, [=](){
        emit ExperimentRunUi::previousEvent();
    });

    /* 下一步按钮 */
    connect(ui->nextBtn, &QPushButton::clicked, this, &ExperimentRunUi::nextCallback);
}

ExperimentRunUi::~ExperimentRunUi()
{
    /* 删除线程 */
    this->runThread->exit(0);
    this->runThread->wait();
    delete this->runThread;
    delete ui;
}

/* 下一步 */
void ExperimentRunUi::nextCallback(){
    /* 发送下一步信号 */
    emit ExperimentRunUi::nextEvent();
}

/* 返回数据信息 */
QHash<QString, QString> ExperimentRunUi::returnPageInfos(){
    return this->targetLegend;
}

/* 获取运行时所需数据 */
//void ExperimentRunUi::getRunTimeData(QString id, ReactionPlate reactionPlate, int totalCycling, Experiment experiment, int volumn, int procedureStepCount, int procedureStageCount, ExperimentService *experimentService, int totalrunningTime){
void ExperimentRunUi::getRunTimeData(){
    qDebug() << "清除横轴数据开始";
    int preXAxisMax = this->expRunXAxis->count();
    /* 清除横轴数据 */
    for(int i = 0; i < preXAxisMax; i++){
        this->expRunXAxis->remove(QString::number(i+1));
        this->expRunChart->update();
    }
    qDebug() << "清除横轴数据结束";

    qDebug() << "获取扩增信息开始";
    /* 获取扩增信息 */
    procedureList = procedureService->getProcedureData(id);
    qDebug() << "获取扩增信息结束";

    qDebug() << "曲线图开始";
    /* 曲线图 */
    /* 设置横轴大小 */
    this->xAxisMaximum = this->totalCycling;
    /* 设置横轴范围 */
    this->expRunXAxis->setRange(0, this->xAxisMaximum-1); // 曲线
    /* 设置横轴刻度 */
    this->expRunXAxis->setTickCount(this->totalCycling); // 曲线
    /* 设置横轴数据 */
    for(int i = 0; i < this->totalCycling; i++){
        this->expRunXAxis->append(QString::number(i+1), i); // 曲线
        expRunChart->update();
    }
    qDebug() << "曲线图结束";

    qDebug() << "渲染数据开始";
    /* 渲染数据 */
    this->renderRunTimeInfo();
    /* 通过反应板数据渲染曲线图例和颜色 */
    this->getReactionPlateTarget();
    // 初始化柱状图图例颜色
    this->curBarVisible = this->initBarLegendStyle();
    // 渲染图例颜色
    this->renderLegendStyle();

    qDebug() << "渲染数据结束";

    qDebug() << "柱状图开始";
    /* 柱状图 */
    this->renderBarXAxisData(); // 渲染柱状图横轴数据
    qDebug() << "柱状图结束";

    return;
}

/* 渲染信息 */
void ExperimentRunUi::renderRunTimeInfo(){
    /* 同步实验信息 */
    /* 同步剩余时间 */
    runningMinute = int(this->totalrunningTime / 60);
    runningSecond = this->totalrunningTime - runningMinute*60;
    ui->labelInfo12->setText(QString::number(runningMinute) + "分" + QString::number(runningSecond) + "秒");
    /* 同步反应体积 */
    ui->labelInfo24->setText(QString::number(this->volumn));
    /* 同步实验名称 */
    ui->labelInfo2->setText(this->experiment.experiment_name);
    /* 同步耗材类型 */
    ui->labelInfo18->setText(this->reactionPlate.consumables);
    /* 同步用户名 */
    ui->labelInfo6->setText(this->experiment.user_name);
    /* 同步设备名称 */
    ui->labelInfo14->setText(ui->runningDevice->currentText());
    /* 同步设备序列号 */
    ui->labelInfo16->setText(cDevS.dev.serial_number);
    /* 同步设备状态 */
    ui->expRunStateLabel->setText(cDevS.dev.status);
    /* 同步颜色样式 */
    if(cDevS.dev.status == "运行中")
        ui->expRunStateLabel->setStyleSheet("QLabel {color: #086700;font-size:16px;font-family: \"Alibaba PuHuiTi\";}");
    else if(cDevS.dev.status == "故障")
        ui->expRunStateLabel->setStyleSheet("QLabel {color: #B60000;font-size:16px;font-family: \"Alibaba PuHuiTi\";}");
    else if(cDevS.dev.status == "已连接")
        ui->expRunStateLabel->setStyleSheet("QLabel {color: #1000EB;font-size:16px;font-family: \"Alibaba PuHuiTi\";}");

    /* 同步反应板 */
    /* 清空反应板 */
    ui->expRunTable->clear();
    RenderTableRowColumnFromXML();

    updateTable();
}

/* 创建曲线图表 */
void ExperimentRunUi::createLineChart(){
    expRunChart = new QChart();
    expRunChart->setTheme(QChart::ChartThemeQt);
    expRunChart->setMargins(QMargins(0, 0, 0, 0));
    expRunChart->setTitle("扩增图谱");

    // 抗锯齿
    ui->lineGraphicsView->setRenderHint(QPainter::Antialiasing);
    // 添加轴
    expRunXAxis = new QCategoryAxis();
    expRunYAxis = new QValueAxis();
    // 坐标轴名称
    expRunXAxis->setTitleText("循环数");
    expRunYAxis->setTitleText("Rn");

    // 让刻度线和刻度的label对齐
    expRunXAxis->setLabelsPosition(QCategoryAxis::AxisLabelsPositionOnValue);
    // 曲线动画效果
    expRunChart->setAnimationOptions(QChart::SeriesAnimations);

    // 坐标轴范围
    expRunXAxis->setStartValue(0);
    expRunXAxis->setRange(0, 0);
    expRunYAxis->setRange(0, yAxisMaximum);
    // 轴标签设置
    expRunXAxis->setLabelFormat("%d");
    expRunYAxis->setLabelFormat("%d");
    /* 设置纵轴副轴刻度 */
    this->expRunYAxis->setMinorTickCount(1);
    // 图例不可见
    expRunChart->legend()->setVisible(false);

    // 绑定数据系列
    for(int i = 0; i < 96; i++){
        QSplineSeries *cy5Series = new QSplineSeries();
        QSplineSeries *famSeries = new QSplineSeries();
        QSplineSeries *vicSeries = new QSplineSeries();
        QSplineSeries *roxSeries = new QSplineSeries();

        // 添加数据序列
        cy5SeriesList.append(cy5Series);
        famSeriesList.append(famSeries);
        vicSeriesList.append(vicSeries);
        roxSeriesList.append(roxSeries);
    }

    for(int i = 0; i < 96; i++){
        expRunChart->addSeries(cy5SeriesList[i]);
        expRunChart->addSeries(famSeriesList[i]);
        expRunChart->addSeries(vicSeriesList[i]);
        expRunChart->addSeries(roxSeriesList[i]);
    }


    for(int i = 0; i < 96; i++){
        // 绑定坐标轴
        expRunChart->setAxisX(expRunXAxis, cy5SeriesList[i]);
        expRunChart->setAxisY(expRunYAxis, cy5SeriesList[i]);
        expRunChart->setAxisX(expRunXAxis, famSeriesList[i]);
        expRunChart->setAxisY(expRunYAxis, famSeriesList[i]);
        expRunChart->setAxisX(expRunXAxis, vicSeriesList[i]);
        expRunChart->setAxisY(expRunYAxis, vicSeriesList[i]);
        expRunChart->setAxisX(expRunXAxis, roxSeriesList[i]);
        expRunChart->setAxisY(expRunYAxis, roxSeriesList[i]);
    }

    /* 在 ChartsView 上渲染 QCharts */
    ui->lineGraphicsView->setChart(expRunChart);

    //修改坐标轴字体
    QFont chartFont, xAxisFont, yAxisFont;
    const int chartFontSize = 9, xAxisFontSize = 6; // y轴标签字体大小是chartFontSize
    chartFont.setFamily("Alibaba PuHuiTi");
    chartFont.setPointSize(chartFontSize);
    chartFont.setBold(true);
    xAxisFont.setFamily("Alibaba PuHuiTi");
    xAxisFont.setPointSize(xAxisFontSize);
    yAxisFont.setFamily("Alibaba PuHuiTi");
    yAxisFont.setPointSize(chartFontSize);
    expRunXAxis->setLabelsFont(xAxisFont);
    expRunXAxis->setTitleFont(chartFont);
    expRunYAxis->setTitleFont(chartFont);
    expRunYAxis->setLabelsFont(yAxisFont);
    expRunChart->setTitleFont(chartFont);

    /* 点击图例，隐藏对应曲线 */
    /* 绑定信号和槽 */
    connect(this, &ExperimentRunUi::sigCurveLabelFilter, this, &ExperimentRunUi::curveLabelFilter);

    /* fam */
    connect(ui->famBtn, &QPushButton::clicked, this, [=](){
        emit ExperimentRunUi::sigCurveLabelFilter("1", ui->legendSelector->currentText());
    });
    connect(ui->famLabel, &QPushButton::clicked, this, [=](){
        emit ExperimentRunUi::sigCurveLabelFilter("1", ui->legendSelector->currentText());
    });

    /* vic */
    connect(ui->vicBtn, &QPushButton::clicked, this, [=](){
        emit ExperimentRunUi::sigCurveLabelFilter("2", ui->legendSelector->currentText());
    });
    connect(ui->vicLabel, &QPushButton::clicked, this, [=](){
        emit ExperimentRunUi::sigCurveLabelFilter("2", ui->legendSelector->currentText());
    });

    /* rox */
    connect(ui->roxBtn, &QPushButton::clicked, this, [=](){
        emit ExperimentRunUi::sigCurveLabelFilter("3", ui->legendSelector->currentText());
    });
    connect(ui->roxLabel, &QPushButton::clicked, this, [=](){
        emit ExperimentRunUi::sigCurveLabelFilter("3", ui->legendSelector->currentText());
    });

    /* cy5 */
    connect(ui->cy5Btn, &QPushButton::clicked, this, [=](){
        emit ExperimentRunUi::sigCurveLabelFilter("4", ui->legendSelector->currentText());
    });

    connect(ui->cy5Label, &QPushButton::clicked, this, [=](){
        emit ExperimentRunUi::sigCurveLabelFilter("4", ui->legendSelector->currentText());
    });

    /* 监测曲线，动态调整y轴最大值 */
    for(QSplineSeries *famSeries : famSeriesList){
        connect(famSeries, &QSplineSeries::pointAdded, this, [=](int index){
            if(this->yAxisMaximum < static_cast<int>(famSeries->points()[index].y())){
                this->yAxisMaximum = static_cast<int>(famSeries->points()[index].y());
                this->expRunYAxis->setMax(this->yAxisMaximum + 1000);
            }
        });
    }
    for(QSplineSeries *vicSeries : vicSeriesList){
        connect(vicSeries, &QSplineSeries::pointAdded, this, [=](int index){
            if(this->yAxisMaximum < static_cast<int>(vicSeries->points()[index].y())){
                this->yAxisMaximum = static_cast<int>(vicSeries->points()[index].y());
                this->expRunYAxis->setMax(this->yAxisMaximum + 1000);
            }
        });
    }
    for(QSplineSeries *roxSeries : roxSeriesList){
        connect(roxSeries, &QSplineSeries::pointAdded, this, [=](int index){
            if(this->yAxisMaximum < static_cast<int>(roxSeries->points()[index].y())){
                this->yAxisMaximum = static_cast<int>(roxSeries->points()[index].y());
                this->expRunYAxis->setMax(this->yAxisMaximum + 1000);
            }
        });
    }
    for(QSplineSeries *cy5Series : cy5SeriesList){
        connect(cy5Series, &QSplineSeries::pointAdded, this, [=](int index){
            if(this->yAxisMaximum < static_cast<int>(cy5Series->points()[index].y())){
                this->yAxisMaximum = static_cast<int>(cy5Series->points()[index].y());
                this->expRunYAxis->setMax(this->yAxisMaximum + 1000);
            }
        });
    }
}

/* 创建柱状图图表 */
void ExperimentRunUi::createBarChart(){
    // 初始化
    expBarChart = new QChart(); // 新建图表
    expBarChart->setTheme(QChart::ChartThemeQt);
    expBarChart->setMargins(QMargins(0, 0, 0, 0));
    expBarChart->setTitle("实时荧光通道强度");
    // 抗锯齿
    ui->lineGraphicsView->setRenderHint(QPainter::Antialiasing);
    // 曲线动画效果
    expBarChart->setAnimationOptions(QChart::SeriesAnimations);
    // 绘制坐标轴
    expBarXAxis = new QBarCategoryAxis(); // 横轴
    expBarYAxis = new QValueAxis(); // 纵轴
    // 坐标轴名称
    expBarXAxis->setTitleText("孔位");
    expBarYAxis->setTitleText("Rn");
    // 坐标轴范围
    expBarYAxis->setRange(0, yAxisMaximum);
    // 轴标签设置
    expBarYAxis->setLabelFormat("%d");
    // 设置y轴辅轴
    expBarYAxis->setMinorTickCount(1);
    // 图例不可见
    expBarChart->legend()->setVisible(false);

    // 新建series
    this->barSeries = new QBarSeries();
    expBarChart->addSeries(this->barSeries); // 图表添加series
    this->barSet = new QBarSet(""); // 创建新组
    this->barSet->setLabelFont(QFont("Alibaba PuHuiTi", MAX_BAR_LABEL_FONT)); // 设置Set标签字体(字体后方的数字为单个字的宽度（实际上为点大小pt）)

    this->barSeries->append(this->barSet); // 将组写入系列
    this->barSeries->setLabelsPosition(QAbstractBarSeries::LabelsPosition::LabelsOutsideEnd); // 设置标签显示位置
    this->barSeries->setLabelsVisible(true); // 显示标签
    // 绑定坐标轴
    this->expBarChart->addAxis(this->expBarXAxis, Qt::AlignBottom);
    this->expBarChart->addAxis(this->expBarYAxis, Qt::AlignLeft);
    this->barSeries->attachAxis(this->expBarXAxis);
    this->barSeries->attachAxis(this->expBarYAxis);

    /* 在 ChartsView 上渲染 QCharts */
    ui->barGraphicsView->setChart(expBarChart);

    //修改坐标轴字体
    QFont chartFont, xAxisFont, yAxisFont;
    const int chartFontSize = 9, xAxisFontSize = 6; // y轴标签字体大小是chartFontSize
    chartFont.setFamily("Alibaba PuHuiTi");
    chartFont.setPointSize(chartFontSize);
    chartFont.setBold(true);
    xAxisFont.setFamily("Alibaba PuHuiTi");
    xAxisFont.setPointSize(xAxisFontSize);
    yAxisFont.setFamily("Alibaba PuHuiTi");
    yAxisFont.setPointSize(chartFontSize);
    expBarXAxis->setLabelsFont(xAxisFont);
    expBarXAxis->setTitleFont(chartFont);
    expBarYAxis->setTitleFont(chartFont);
    expBarYAxis->setLabelsFont(yAxisFont);
    expBarChart->setTitleFont(chartFont);

    // 根据柱状图的最大set的值渲染y轴最大值
    connect(this->barSet, &QBarSet::valuesAdded, this, [=](int index, int count){
        double val = this->barSet->at(index);

        if(this->yAxisMaximum < val){
            this->yAxisMaximum = val + 7000;
        }
        this->expBarYAxis->setRange(0, this->yAxisMaximum + 7000); // 渲染最大值
        this->barSetCount = count; // 记录柱状图组数量
    });

}

/* 初始化柱状图图例颜色 */
QString ExperimentRunUi::initBarLegendStyle(){
    QString res;
    // 通过获取targetLegend的第一个非空key，来设置初始化柱状图图例
    for(int i = 0; i < 4; i++){
        QString key = QString::number(i+1);
        if(this->targetLegend[key] != ""){ // 如果当前key的value不为空
            res = key; // 所要的结果
            break;
        }
    }
    return res;
}

/* 根据反应板孔位选择，渲染横轴数据 */
void ExperimentRunUi::renderBarXAxisData(){
    // 初始化
    this->expBarXAxis->clear();
    this->expBarXAxis->setLabelsVisible(false);
    expBarXAxis->setTitleVisible(false);

    int rowCount = ui->expRunTable->rowCount(),
            columnCount = this->reactionPlate.consumables.contains("16") ? 2 : 4; // 根据耗材类型判断列数
    QStringList barXLabel = {};

    for(int i = 0; i < columnCount; i++){
        for(int j = 0; j < rowCount; j++){
            QString rowLabel = ui->expRunTable->verticalHeaderItem(j)->text(); // 获取行下标
            if(ui->expRunTable->cellWidget(j, i)->findChildren<QLabel *>().size() != 0){
                barXLabel << (rowLabel + QString::number(i+1));
            }
        }
    }

    this->expBarXAxis->append(barXLabel);

    // 坐标轴名称
    if(barXLabel.size() != 0){
        this->expBarXAxis->setLabelsVisible(true);
        expBarXAxis->setTitleVisible(true);
    }

    return;
}

/* 开始运行 */
void ExperimentRunUi::expStartRunning(){
    /* 判断是否开始实验 */
    if(QMessageBox::Yes == cusMsg->show(this, CMsg::CQuestion, "实验开始", "是否开始实验？")){
        /* 实验id为空 */
        if(id == ""){
            cusMsg->show(this, CMsg::CWarning, "警告", "请先输入实验id！");
            ui->startBtn->setStyleSheet(
                        "font-family: 'Alibaba PuHuiTi';"
                        "color: #fff;"
                        "font-size: 18px;"
                        "font-weight: bold;"
                        "border-radius: 8px;"
                        "background-color: rgb(0, 170, 127);");
            return;
        }
        /* 机器故障 */
        else if(ui->expRunStateLabel->text() == "故障"){
            cusMsg->show(this, CMsg::CCritical, "错误", "请尝试解决机器故障后，再重新运行试验！");
            ui->startBtn->setStyleSheet(
                        "font-family: 'Alibaba PuHuiTi';"
                        "color: #fff;"
                        "font-size: 18px;"
                        "font-weight: bold;"
                        "border-radius: 8px;"
                        "background-color: rgb(0, 170, 127);");
            return;
        }
        /* 已连接实验设备列表为空 */
        else if(ui->runningDevice->count() == 0){
            cusMsg->show(this, CMsg::CWarning, "警告", "请至少连接一台可用设备！");

            ui->startBtn->setStyleSheet(
                        "font-family: 'Alibaba PuHuiTi';"
                        "color: #fff;"
                        "font-size: 18px;"
                        "font-weight: bold;"
                        "border-radius: 8px;"
                        "background-color: rgb(0, 170, 127);");
            return;
        }
        /* 当前设备无效 */
        else if(ui->expRunStateLabel->text() == "未知"){
            cusMsg->show(this, CMsg::CWarning, "警告", "当前所选设备无效，不能开始实验！");

            ui->startBtn->setStyleSheet(
                        "font-family: 'Alibaba PuHuiTi';"
                        "color: #fff;"
                        "font-size: 18px;"
                        "font-weight: bold;"
                        "border-radius: 8px;"
                        "background-color: rgb(0, 170, 127);");
            return;
        }
        /* 反应板为空 */
        else if(this->reactionPlateDataIsEmpty()){
            cusMsg->show(this, CMsg::CWarning, "警告", "反应板数据为空！");
            ui->startBtn->setStyleSheet(
                        "font-family: 'Alibaba PuHuiTi';"
                        "color: #fff;"
                        "font-size: 18px;"
                        "font-weight: bold;"
                        "border-radius: 8px;"
                        "background-color: rgb(0, 170, 127);");
            return;
        }
        /* 荧光曲线有数据 */
        else if(this->saveYingguangDataList.size() != 0){
            cusMsg->show(this, CMsg::CWarning, "警告", "该实验运行完成并生成荧光检测数据，不能再次启动！");
            ui->startBtn->setStyleSheet(
                        "font-family: 'Alibaba PuHuiTi';"
                        "color: #fff;"
                        "font-size: 18px;"
                        "font-weight: bold;"
                        "border-radius: 8px;"
                        "background-color: rgb(0, 170, 127);");
            return;
        }
        /* 当前所选设备正在运行 */
        else if(cDevS.dev.status.contains("运行")){
            cusMsg->show(this, CMsg::CWarning, "警告", "当前所选设备正在运行中，请重新选择设备运行！");
            ui->startBtn->setStyleSheet(
                        "font-family: 'Alibaba PuHuiTi';"
                        "color: #fff;"
                        "font-size: 18px;"
                        "font-weight: bold;"
                        "border-radius: 8px;"
                        "background-color: rgb(0, 170, 127);");
            return;
        }
        /* 实验开始运行 */
        else {
            /* 保存实验信息 */
            emit ExperimentRunUi::startSaveExperimentInfo();
            /* 暂时休眠，等待函数执行到阻塞态 */
            this->sleep(50);
            if(this->runFlag){
                /* 获取当前日期时间 */
                QDateTime expTime = QDateTime::currentDateTime();
                /* 转QString */
                QString expStringDate = expTime.toString("yyyy-MM-dd");
                QString expHour = expTime.toString("hh");
                QString expMinute = expTime.toString("mm");
                QString expStringSecond = expTime.toString("ss");
                /* 渲染实验开始时间 */
                QString expBeginTime = expStringDate + " " + expHour + expMinute + expStringSecond;
                ui->labelInfo10->setText(expBeginTime);
                /* 获取实验结束时间 */
                int totalHour = expHour.toInt();
                int totalMinute = this->totalrunningTime/60;
                int totalSecond = this->totalrunningTime - totalMinute*60;

                /* 当前时间加上运行时间 */
                totalMinute = totalMinute + expMinute.toInt();
                totalSecond = totalSecond + expStringSecond.toInt();

                LOG << "totalHour1" << totalHour << "totalMinute1" << totalMinute << "totalSecond1" << totalSecond;

                /* 时间进位 */
                totalMinute = totalMinute + int(totalSecond/60);
                totalHour = totalHour + int(totalMinute/60);

                /* 进位后的时间 */
                totalSecond = totalSecond - int(totalSecond/60)*60;
                totalMinute = totalMinute - int(totalMinute/60)*60;

                LOG << "totalHour2" << totalHour << "totalMinute2" << totalMinute << "totalSecond2" << totalSecond;

                /* 大于23点，置为0 */
                if(totalHour > 23) totalHour = 0;
                /* 渲染结束时间 */
                QString expEndTime;
                if(totalMinute < 10)
                    expEndTime = expStringDate + " " + QString::number(totalHour) + "0" + QString::number(totalMinute) + QString::number(totalSecond);
                else if(totalSecond < 10)
                    expEndTime = expStringDate + " " + QString::number(totalHour) + QString::number(totalMinute) + "0" + QString::number(totalSecond);
                else if(totalHour < 10)
                    expEndTime = expStringDate + " " + "0" + QString::number(totalHour) + QString::number(totalMinute) + QString::number(totalSecond);
                else if(totalSecond < 10 && totalMinute < 10)
                    expEndTime = expStringDate + " " + QString::number(totalHour) + "0" + QString::number(totalMinute) + "0" + QString::number(totalSecond);
                else if(totalSecond < 10 && totalHour < 10)
                    expEndTime = expStringDate + " " + "0" + QString::number(totalHour) + QString::number(totalMinute) + "0" + QString::number(totalSecond);
                else if(totalHour < 10 && totalMinute < 10)
                    expEndTime = expStringDate + " " + "0" + QString::number(totalHour) + "0" + QString::number(totalMinute) + QString::number(totalSecond);
                else if(totalHour < 10 && totalMinute < 10 && totalHour < 10)
                    expEndTime = expStringDate + " " + "0" + QString::number(totalHour) + "0" + QString::number(totalMinute) + "0" + QString::number(totalSecond);
                else
                    expEndTime = expStringDate + " " + QString::number(totalHour) + QString::number(totalMinute) + QString::number(totalSecond);

                LOG << "expEndTime" << expEndTime;

                ui->labelInfo4->setText(expEndTime);

                /* 渲染运行初始步骤 */
                this->currentProcedureStepCount = 1;
                this->setSize = 0;
                /* 获取实验预计时间 */
                saveTotalrunningTime = this->totalrunningTime;
                totalMinute = this->totalrunningTime/60;
                totalSecond = this->totalrunningTime - (this->totalrunningTime/60)*60;
                ui->labelInfo12->setText(QString::number(totalMinute) + "分" + QString::number(totalSecond) + "秒");
                /* 渲染实验说明 */
                ui->info_2->setText(ui->labelInfo12->text());
                ui->info_4->setText("0分0秒");
                /* 渲染标签 */
                ui->stepNo->setText(QString::number(this->currentProcedureStepCount));
                ui->cyclingNo->setText(QString::number(currentCycling));
                /* 清空集合 */
                currentYinggangSymbolDataSet.clear();
                saveYingguangDataList.clear();
                saveYingguangList.clear();
                /* 初始化flag */
                this->timerFlag = 0;
                /* 传入设备信息 */
                this->experiment.device_id = cDevS.dev.id;
                /* 更新数据库实验设备信息 */
                this->experimentService->update(this->experiment);
                /* 实验启动标识位设为1 */
                this->experimentService->updateStateStart(this->id.toInt());

                /* 所有按钮失效 */
                ui->startBtn->setEnabled(false);
                ui->pauseOrContinueBtn->setEnabled(false);
                /* 其他按钮生效 */
                ui->stopBtn->setEnabled(true);

                ui->startBtn->setStyleSheet(
                            "font-family: 'Alibaba PuHuiTi';"
                            "color: #fff;"
                            "font-size: 18px;"
                            "font-weight: bold;"
                            "border-radius: 8px;"
                            "background-color: #a2a2a2;");

                ui->stopBtn->setStyleSheet(
                            "font-family: 'Alibaba PuHuiTi';"
                            "color: #fff;"
                            "font-size: 18px;"
                            "font-weight: bold;"
                            "border-radius: 8px;"
                            "background-color: #fe7272;");

                /* 修改设备状态 */
                for(int i = 0; i < connectDeviceInfo.size(); i++){
                    if(cDevS.dev.id == connectDeviceInfo[i].dev.id){
                        connectDeviceInfo[i].dev.status = "运行中";
                        cDevS.dev.status = "运行中";
                        break;
                    }
                }

                /* 渲染活跃设备列表 */
                emit ExperimentRunUi::updateInactiveDeviceList();

                /* 清空集合 */
                cDevS.instructionsService->yangBenData.clear();
                cDevS.instructionsService->kuoZengData.clear();
                cDevS.instructionsService->guZhangData.clear();
                ui->textEdit_mistake->clear();
                /* 关闭故障显示页面 */
                ui->errorWidget->hide();
                /* 修改运行旗帜 */
                this->runFlag = true;

                /* 改变文字和按钮样式 */
                ui->expRunStateLabel->setText(cDevS.dev.status);
                /* 同步颜色样式 */
                if(cDevS.dev.status == "运行中")
                    ui->expRunStateLabel->setStyleSheet("QLabel {color: #086700;font-size:16px;font-family: \"Alibaba PuHuiTi\";}");
                else if(cDevS.dev.status == "故障")
                    ui->expRunStateLabel->setStyleSheet("QLabel {color: #B60000;font-size:16px;font-family: \"Alibaba PuHuiTi\";}");
                else if(cDevS.dev.status == "已连接")
                    ui->expRunStateLabel->setStyleSheet("QLabel {color: #1000EB;font-size:16px;font-family: \"Alibaba PuHuiTi\";}");

                /* 清空结果曲线 */
                emit ExperimentRunUi::clearResultCurve();

                /* 渲染运行状态颜色到Tab页上 */
                emit ExperimentRunUi::sigShowRunningStatus("运行");

                /* 发送信号：更新实验实验恢复列表实验设备 */
                emit ExperimentRunUi::renderRestoreList();

                /* 定时器开始计时 */
                this->runningTimer->start(1000);

                QStringList procedureStringList, reactionPlateStringList;

                /* 获取扩增数据 */
                QHash<QHash<QString,QString>,QList<QHash<QString,QString>>> procedureDataList = procedureService->getProcedureData(id);
                LOG << "procedureDataList" << procedureDataList << "~~~~~~~~~~~~~~~~~~~~~~~~";
                QString procedureData = convertion->getProcedureData(procedureDataList, id);
                LOG << "procedureData" << procedureData << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~";
                /* 获取反应板数据 */
                QString reactionPlateData = convertion->getReactionPlateData(reactionPlate, id);
                /* 发送指令 */
                // 扩增一次判定
                procedureStringList = this->procedureCallback(cDevS, procedureData);
                // 扩增一次判定返回值不为空
                if(procedureStringList.size() != 0 && this->runFlag){
                    // 扩增一次判定成功
                    if(procedureStringList[2].contains("成功") && this->runFlag){
                        // 反应板一次判定
                        reactionPlateStringList = reactionPlateCallback(cDevS, reactionPlateData);
                        // 反应板一次判定返回值不为空
                        if(reactionPlateStringList.size() != 0 && this->runFlag){
                            // 反应板一次判定成功
                            if(reactionPlateStringList[2].contains("成功") && this->runFlag){
                                /* 线程启动 */
                                this->runThread->start();
                            }
                            // 反应板一次判定失败
                            else if(reactionPlateStringList[2].contains("失败") && this->runFlag) {
                                // 反应板二次判断
                                reactionPlateStringList = reactionPlateCallback(cDevS, reactionPlateData);
                                // 反应板二次判断不为空
                                if(reactionPlateStringList.size() != 0 && this->runFlag){
                                    // 反应板二次判定成功
                                    if(reactionPlateStringList[2].contains("成功" && this->runFlag)){
                                        /* 线程启动 */
                                        this->runThread->start();
                                    }
                                    // 反应板二次判定失败
                                    else if(reactionPlateStringList[2].contains("失败" && this->runFlag)){
                                        cusMsg->show(this, CMsg::CCritical, "反应板数据回传", "反应板内容回传失败！"
                                                                                       "请检查设备是否断线或有其他故障！");

                                        ui->expRunStateLabel->setText("已连接");
                                        ui->expRunStateLabel->setStyleSheet("QLabel {color: #1000EB;font-size:16px;font-family: \"Alibaba PuHuiTi\";}");
                                        /* socket关闭 */
                                        //                                if(cDevS.instructionsService->m_socketClient->isConnected()){
                                        //                                    cDevS.instructionsService->m_socketClient->closeSocket();
                                        //                                }

                                        /* 渲染故障 */
                                        ui->textEdit_mistake->append("反应板回传信息是失败");
                                        ui->errorWidget->show();
                                        ui->errMsg->setPlainText("反应板回传信息是失败");

                                        /* 修改设备状态 */
                                        for(int i = 0; i < connectDeviceInfo.size(); i++){
                                            if(cDevS.dev.id == connectDeviceInfo[i].dev.id){
                                                connectDeviceInfo[i].dev.status = "已连接";
                                                cDevS.dev.status = "已连接";
                                                break;
                                            }
                                        }

                                        /* 运行计时器停止 */
                                        this->runningTimer->stop();

                                        /* 将Tab状态颜色改变 */
                                        emit ExperimentRunUi::sigShowRunningStatus("已连接");

                                        /* 停止线程 */
                                        this->runThread->quit();
                                        this->runThread->wait();

                                        return;
                                    }
                                    // 反应板二次判定故障
                                    else if(this->runFlag) {
                                        /* 强制跳转到扩增曲线页 */
                                        ui->runningTimeTab->setCurrentIndex(1);
                                        ui->expRunStateLabel->setText("故障");
                                        ui->expRunStateLabel->setStyleSheet("QLabel {color: #B60000;font-size:16px;font-family: \"Alibaba PuHuiTi\";}");
                                        /* 渲染故障 */
                                        ui->textEdit_mistake->append(reactionPlateStringList[2]);
                                        ui->errorWidget->show();
                                        ui->errMsg->setPlainText(reactionPlateStringList[2]);
                                        cusMsg->show(this, CMsg::CCritical, "错误", "设备故障！");
                                        /* socket关闭 */
                                        //                                if(cDevS.instructionsService->m_socketClient->isConnected()){
                                        //                                    cDevS.instructionsService->m_socketClient->closeSocket();
                                        //                                }

                                        /* 修改设备状态 */
                                        for(int i = 0; i < connectDeviceInfo.size(); i++){
                                            if(cDevS.dev.id == connectDeviceInfo[i].dev.id){
                                                connectDeviceInfo[i].dev.status = "故障";
                                                cDevS.dev.status = "故障";
                                                break;
                                            }
                                        }

                                        /* 运行计时器停止 */
                                        this->runningTimer->stop();

                                        /* 将Tab状态颜色改变 */
                                        emit ExperimentRunUi::sigShowRunningStatus("故障");

                                        /* 停止线程 */
                                        this->runThread->quit();
                                        this->runThread->wait();

                                        return;
                                    }
                                }
                                // 反应板二次判定为空
                                else if(this->runFlag) {
                                    cusMsg->show(this, CMsg::CCritical, "回传失败", "回传信息为空！");

                                    /* 重置时间为null */
                                    ui->expRunStateLabel->setText("已连接");
                                    ui->expRunStateLabel->setStyleSheet("QLabel {color: #1000EB;font-size:16px;font-family: \"Alibaba PuHuiTi\";}");
                                    QDateTime current_date_time =QDateTime::currentDateTime();
                                    QString current_date = current_date_time.toString("yyyy/MM/dd hh:mm:ss.zzz");
                                    /* 渲染故障 */
                                    ui->textEdit_mistake->append(current_date + " 通信失败：反应板回传信息为空");
                                    ui->errorWidget->show();
                                    ui->errMsg->setPlainText("通信失败；反应板回传信息为空");
                                    cusMsg->show(this, CMsg::CCritical, "错误", "设备故障！");
                                    /* socket关闭 */
                                    //                            if(cDevS.instructionsService->m_socketClient->isConnected()){
                                    //                                cDevS.instructionsService->m_socketClient->closeSocket();
                                    //                            }

                                    /* 修改设备状态 */
                                    for(int i = 0; i < connectDeviceInfo.size(); i++){
                                        if(cDevS.dev.id == connectDeviceInfo[i].dev.id){
                                            connectDeviceInfo[i].dev.status = "已连接";
                                            cDevS.dev.status = "已连接";
                                            break;
                                        }
                                    }

                                    /* 运行计时器停止 */
                                    this->runningTimer->stop();

                                    /* 将Tab状态颜色改变 */
                                    emit ExperimentRunUi::sigShowRunningStatus("已连接");

                                    /* 停止线程 */
                                    this->runThread->quit();
                                    this->runThread->wait();
                                    return;
                                }
                            }
                            // 反应板一次判定故障
                            else if(this->runFlag) {
                                /* 强制跳转到扩增曲线页 */
                                ui->runningTimeTab->setCurrentIndex(1);
                                ui->expRunStateLabel->setText("故障");
                                ui->expRunStateLabel->setStyleSheet("QLabel {color: #B60000;font-size:16px;font-family: \"Alibaba PuHuiTi\";}");
                                /* 渲染故障 */
                                ui->textEdit_mistake->append(reactionPlateStringList[2]);
                                ui->errorWidget->show();
                                ui->errMsg->setPlainText(reactionPlateStringList[2]);
                                cusMsg->show(this, CMsg::CCritical, "错误", "设备故障！");
                                /* socket关闭 */
                                //                        if(cDevS.instructionsService->m_socketClient->isConnected()){
                                //                            cDevS.instructionsService->m_socketClient->closeSocket();
                                //                        }

                                /* 修改设备状态 */
                                for(int i = 0; i < connectDeviceInfo.size(); i++){
                                    if(cDevS.dev.id == connectDeviceInfo[i].dev.id){
                                        connectDeviceInfo[i].dev.status = "故障";
                                        cDevS.dev.status = "故障";
                                        break;
                                    }
                                }

                                /* 运行计时器停止 */
                                this->runningTimer->stop();

                                /* 将Tab状态颜色改变 */
                                emit ExperimentRunUi::sigShowRunningStatus("故障");

                                /* 停止线程 */
                                this->runThread->quit();
                                this->runThread->wait();
                                return;
                            }
                        }
                        // 反应板一次判定返回值为空
                        else if(this->runFlag) {
                            // 反应板二次判定
                            reactionPlateStringList = reactionPlateCallback(cDevS, reactionPlateData);
                            // 反应板二次判定返回值不为空
                            if(reactionPlateStringList.size()  != 0 && this->runFlag){
                                // 反应板二次判定成功
                                if(reactionPlateStringList[2].contains("成功") && this->runFlag){
                                    /* 线程启动 */
                                    this->runThread->start();
                                }
                                // 反应板二次判定失败
                                else if(reactionPlateStringList[2].contains("失败") && this->runFlag) {
                                    cusMsg->show(this, CMsg::CCritical, "反应板数据回传", "反应板内容回传失败！"
                                                                                   "请检查设备是否断线或有其他故障！");
                                    /* 重置时间为null */
                                    ui->expRunStateLabel->setText("已连接");
                                    ui->expRunStateLabel->setStyleSheet("QLabel {color: #1000EB;font-size:16px;font-family: \"Alibaba PuHuiTi\";}");
                                    /* 渲染故障 */
                                    ui->textEdit_mistake->append("反应板回传信息失败");
                                    ui->errorWidget->show();
                                    ui->errMsg->setPlainText("反应板回传信息失败");
                                    /* socket关闭 */
                                    //                            if(cDevS.instructionsService->m_socketClient->isConnected()){
                                    //                                cDevS.instructionsService->m_socketClient->closeSocket();
                                    //                            }

                                    /* 修改设备状态 */
                                    for(int i = 0; i < connectDeviceInfo.size(); i++){
                                        if(cDevS.dev.id == connectDeviceInfo[i].dev.id){
                                            connectDeviceInfo[i].dev.status = "已连接";
                                            cDevS.dev.status = "已连接";
                                            break;
                                        }
                                    }

                                    /* 运行计时器停止 */
                                    this->runningTimer->stop();

                                    /* 将Tab状态颜色改变 */
                                    emit ExperimentRunUi::sigShowRunningStatus("已连接");

                                    /* 停止线程 */
                                    this->runThread->quit();
                                    this->runThread->wait();
                                    return;
                                }
                                // 反应板二次判定故障
                                else if(this->runFlag) {
                                    /* 强制跳转到扩增曲线页 */
                                    ui->runningTimeTab->setCurrentIndex(1);
                                    ui->expRunStateLabel->setText("故障");
                                    ui->expRunStateLabel->setStyleSheet("QLabel {color: #B60000;font-size:16px;font-family: \"Alibaba PuHuiTi\";}");
                                    /* 渲染故障 */
                                    ui->textEdit_mistake->append(reactionPlateStringList[2]);
                                    ui->errorWidget->show();
                                    ui->errMsg->setPlainText(reactionPlateStringList[2]);
                                    cusMsg->show(this, CMsg::CCritical, "错误", "设备故障！");
                                    /* socket关闭 */
                                    //                            if(cDevS.instructionsService->m_socketClient->isConnected()){
                                    //                                cDevS.instructionsService->m_socketClient->closeSocket();
                                    //                            }

                                    /* 修改设备状态 */
                                    for(int i = 0; i < connectDeviceInfo.size(); i++){
                                        if(cDevS.dev.id == connectDeviceInfo[i].dev.id){
                                            connectDeviceInfo[i].dev.status = "故障";
                                            cDevS.dev.status = "故障";
                                            break;
                                        }
                                    }

                                    /* 运行计时器停止 */
                                    this->runningTimer->stop();

                                    /* 将Tab状态颜色改变 */
                                    emit ExperimentRunUi::sigShowRunningStatus("故障");

                                    /* 停止线程 */
                                    this->runThread->quit();
                                    this->runThread->wait();
                                    return;
                                }
                            }
                            // 反应板二次判定返回值为空
                            else if(this->runFlag) {
                                cusMsg->show(this, CMsg::CCritical, "回传失败", "回传信息为空！");
                                QDateTime current_date_time =QDateTime::currentDateTime();
                                QString current_date = current_date_time.toString("yyyy/MM/dd hh:mm:ss.zzz");
                                /* 渲染故障 */
                                ui->textEdit_mistake->append(current_date + " 通信失败：反应板回传信息为空");
                                ui->errorWidget->show();
                                ui->errMsg->setPlainText("通信失败：反应板回传信息为空");
                                /* 重置时间为null */
                                ui->expRunStateLabel->setText("已连接");
                                ui->expRunStateLabel->setStyleSheet("QLabel {color: #1000EB;font-size:16px;font-family: \"Alibaba PuHuiTi\";}");
                                /* socket关闭 */
                                //                        if(cDevS.instructionsService->m_socketClient->isConnected()){
                                //                            cDevS.instructionsService->m_socketClient->closeSocket();
                                //                        }

                                /* 修改设备状态 */
                                for(int i = 0; i < connectDeviceInfo.size(); i++){
                                    if(cDevS.dev.id == connectDeviceInfo[i].dev.id){
                                        connectDeviceInfo[i].dev.status = "已连接";
                                        cDevS.dev.status = "已连接";
                                        break;
                                    }
                                }

                                /* 运行计时器停止 */
                                this->runningTimer->stop();

                                /* 将Tab状态颜色改变 */
                                emit ExperimentRunUi::sigShowRunningStatus("已连接");

                                /* 停止线程 */
                                this->runThread->quit();
                                this->runThread->wait();
                                return;
                            }
                        }
                    }
                    // 扩增一次判定失败
                    else if(procedureStringList[2].contains("失败") && this->runFlag){
                        // 扩增二次判定
                        procedureStringList = this->procedureCallback(cDevS, procedureData);
                        // 扩增二次判定返回值不为空
                        if(procedureStringList.size() != 0){
                            // 扩增二次判定成功
                            if(procedureStringList[2].contains("成功") && this->runFlag){
                                // 反应板一次判定
                                reactionPlateStringList = reactionPlateCallback(cDevS, reactionPlateData);
                                // 反应板一次判定返回值不为空
                                if(reactionPlateStringList.size()  != 0 && this->runFlag){
                                    // 反应板一次判定成功
                                    if(reactionPlateStringList[2].contains("成功") && this->runFlag){
                                        /* 线程启动 */
                                        this->runThread->start();
                                    }
                                    // 反应板一次判定失败
                                    else if(reactionPlateStringList[2].contains("失败") && this->runFlag) {
                                        // 反应板二次判定
                                        reactionPlateStringList = reactionPlateCallback(cDevS, reactionPlateData);
                                        // 反应板二次判定返回值不为空
                                        if(reactionPlateStringList.size()  != 0 && this->runFlag){
                                            // 反应板二次判定成功
                                            if(reactionPlateStringList[2].contains("成功") && this->runFlag){
                                                /* 线程启动 */
                                                this->runThread->start();
                                            }
                                            // 反应板二次判定失败
                                            else if(reactionPlateStringList[2].contains("失败") && this->runFlag){
                                                cusMsg->show(this, CMsg::CCritical, "反应板数据回传", "反应板内容回传失败！"
                                                                                               "请检查设备是否断线或有其他故障！");
                                                /* 渲染故障 */
                                                ui->textEdit_mistake->append("反应板回传信息是失败");
                                                ui->errorWidget->show();
                                                ui->errMsg->setPlainText("反应板回传信息是失败");
                                                /* 重置时间为null */
                                                ui->expRunStateLabel->setText("已连接");
                                                ui->expRunStateLabel->setStyleSheet("QLabel {color: #1000EB;font-size:16px;font-family: \"Alibaba PuHuiTi\";}");
                                                /* socket关闭 */
                                                //                                        if(cDevS.instructionsService->m_socketClient->isConnected()){
                                                //                                            cDevS.instructionsService->m_socketClient->closeSocket();
                                                //                                        }

                                                /* 修改设备状态 */
                                                for(int i = 0; i < connectDeviceInfo.size(); i++){
                                                    if(cDevS.dev.id == connectDeviceInfo[i].dev.id){
                                                        connectDeviceInfo[i].dev.status = "已连接";
                                                        cDevS.dev.status = "已连接";
                                                        break;
                                                    }
                                                }

                                                /* 运行计时器停止 */
                                                this->runningTimer->stop();

                                                /* 将Tab状态颜色改变 */
                                                emit ExperimentRunUi::sigShowRunningStatus("已连接");

                                                /* 停止线程 */
                                                this->runThread->quit();
                                                this->runThread->wait();
                                                return;
                                            }
                                            // 反应板二次判定故障
                                            else if(this->runFlag) {
                                                /* 强制跳转到扩增曲线页 */
                                                ui->runningTimeTab->setCurrentIndex(1);
                                                ui->expRunStateLabel->setText("故障");
                                                ui->expRunStateLabel->setStyleSheet("QLabel {color: #B60000;font-size:16px;font-family: \"Alibaba PuHuiTi\";}");
                                                /* 渲染故障 */
                                                ui->textEdit_mistake->append(reactionPlateStringList[2]);
                                                ui->errorWidget->show();
                                                ui->errMsg->setPlainText(reactionPlateStringList[2]);
                                                cusMsg->show(this, CMsg::CCritical, "错误", "设备故障！");
                                                /* socket关闭 */
                                                //                                        if(cDevS.instructionsService->m_socketClient->isConnected()){
                                                //                                            cDevS.instructionsService->m_socketClient->closeSocket();
                                                //                                        }

                                                /* 修改设备状态 */
                                                for(int i = 0; i < connectDeviceInfo.size(); i++){
                                                    if(cDevS.dev.id == connectDeviceInfo[i].dev.id){
                                                        connectDeviceInfo[i].dev.status = "故障";
                                                        cDevS.dev.status = "故障";
                                                        break;
                                                    }
                                                }

                                                /* 运行计时器停止 */
                                                this->runningTimer->stop();

                                                /* 将Tab状态颜色改变 */
                                                emit ExperimentRunUi::sigShowRunningStatus("故障");

                                                /* 停止线程 */
                                                this->runThread->quit();
                                                this->runThread->wait();
                                                return;
                                            }
                                        }
                                        // 反应板二次判定返回值为空
                                        else if(this->runFlag) {
                                            cusMsg->show(this, CMsg::CCritical, "回传失败", "回传信息为空！");
                                            /* 重置时间为null */
                                            ui->expRunStateLabel->setText("已连接");
                                            ui->expRunStateLabel->setStyleSheet("QLabel {color: #1000EB;font-size:16px;font-family: \"Alibaba PuHuiTi\";}");
                                            QDateTime current_date_time =QDateTime::currentDateTime();
                                            QString current_date = current_date_time.toString("yyyy/MM/dd hh:mm:ss.zzz");
                                            /* 渲染故障 */
                                            ui->textEdit_mistake->append(current_date + " 通信失败：反应板回传信息为空");
                                            ui->errorWidget->show();
                                            ui->errMsg->setPlainText("通信失败：反应板回传信息为空");
                                            /* socket关闭 */
                                            //                                    if(cDevS.instructionsService->m_socketClient->isConnected()){
                                            //                                        cDevS.instructionsService->m_socketClient->closeSocket();
                                            //                                    }

                                            /* 修改设备状态 */
                                            for(int i = 0; i < connectDeviceInfo.size(); i++){
                                                if(cDevS.dev.id == connectDeviceInfo[i].dev.id){
                                                    connectDeviceInfo[i].dev.status = "已连接";
                                                    cDevS.dev.status = "已连接";
                                                    break;
                                                }
                                            }

                                            /* 运行计时器停止 */
                                            this->runningTimer->stop();

                                            /* 将Tab状态颜色改变 */
                                            emit ExperimentRunUi::sigShowRunningStatus("已连接");

                                            /* 停止线程 */
                                            this->runThread->quit();
                                            this->runThread->wait();
                                            return;
                                        }
                                    }
                                    // 反应板一次判定故障
                                    else if(this->runFlag) {
                                        /* 强制跳转到扩增曲线页 */
                                        ui->runningTimeTab->setCurrentIndex(1);
                                        ui->expRunStateLabel->setText("故障");
                                        ui->expRunStateLabel->setStyleSheet("QLabel {color: #B60000;font-size:16px;font-family: \"Alibaba PuHuiTi\";}");
                                        /* 渲染故障 */
                                        ui->textEdit_mistake->append(reactionPlateStringList[2]);
                                        ui->errorWidget->show();
                                        ui->errMsg->setPlainText(reactionPlateStringList[2]);
                                        cusMsg->show(this, CMsg::CCritical, "错误", "设备故障！");
                                        /* socket关闭 */
                                        //                                if(cDevS.instructionsService->m_socketClient->isConnected()){
                                        //                                    cDevS.instructionsService->m_socketClient->closeSocket();
                                        //                                }

                                        /* 修改设备状态 */
                                        for(int i = 0; i < connectDeviceInfo.size(); i++){
                                            if(cDevS.dev.id == connectDeviceInfo[i].dev.id){
                                                connectDeviceInfo[i].dev.status = "故障";
                                                cDevS.dev.status = "故障";
                                                break;
                                            }
                                        }

                                        /* 运行计时器停止 */
                                        this->runningTimer->stop();

                                        /* 将Tab状态颜色改变 */
                                        emit ExperimentRunUi::sigShowRunningStatus("故障");

                                        /* 停止线程 */
                                        this->runThread->quit();
                                        this->runThread->wait();
                                        return;
                                    }
                                }
                                // 反应板一次判定返回值为空
                                else if(this->runFlag) {
                                    // 反应板二次判定
                                    reactionPlateStringList = reactionPlateCallback(cDevS, reactionPlateData);
                                    // 反应板二次判定返回值不为空
                                    if(reactionPlateStringList.size() != 0 && this->runFlag){
                                        // 反应板二次判定成功
                                        if(reactionPlateStringList[2].contains("成功") && this->runFlag){
                                            /* 线程启动 */
                                            this->runThread->start();
                                        }
                                        // 反应板二次判定失败
                                        else if(reactionPlateStringList[2].contains("失败") && this->runFlag) {
                                            cusMsg->show(this, CMsg::CCritical, "反应板数据回传", "反应板内容回传失败！"
                                                                                           "请检查设备是否断线或有其他故障！");
                                            /* 重置时间为null */
                                            ui->expRunStateLabel->setText("已连接");
                                            ui->expRunStateLabel->setStyleSheet("QLabel {color: #1000EB;font-size:16px;font-family: \"Alibaba PuHuiTi\";}");
                                            /* 渲染故障 */
                                            ui->textEdit_mistake->append("反应板回传信息是失败");
                                            ui->errorWidget->show();
                                            ui->errMsg->setPlainText("反应板回传信息是失败");
                                            /* socket关闭 */
                                            //                                    if(cDevS.instructionsService->m_socketClient->isConnected()){
                                            //                                        cDevS.instructionsService->m_socketClient->closeSocket();
                                            //                                    }

                                            /* 修改设备状态 */
                                            for(int i = 0; i < connectDeviceInfo.size(); i++){
                                                if(cDevS.dev.id == connectDeviceInfo[i].dev.id){
                                                    connectDeviceInfo[i].dev.status = "已连接";
                                                    cDevS.dev.status = "已连接";
                                                    break;
                                                }
                                            }

                                            /* 运行计时器停止 */
                                            this->runningTimer->stop();

                                            /* 将Tab状态颜色改变 */
                                            emit ExperimentRunUi::sigShowRunningStatus("已连接");

                                            /* 停止线程 */
                                            this->runThread->quit();
                                            this->runThread->wait();
                                            return;
                                        }
                                        // 反应板二次判定故障
                                        else if(this->runFlag) {
                                            /* 强制跳转到扩增曲线页 */
                                            ui->runningTimeTab->setCurrentIndex(1);
                                            ui->expRunStateLabel->setText("故障");
                                            ui->expRunStateLabel->setStyleSheet("QLabel {color: #B60000;font-size:16px;font-family: \"Alibaba PuHuiTi\";}");
                                            /* 渲染故障 */
                                            ui->textEdit_mistake->append(reactionPlateStringList[2]);
                                            ui->errorWidget->show();
                                            ui->errMsg->setPlainText(reactionPlateStringList[2]);
                                            cusMsg->show(this, CMsg::CCritical, "错误", "设备故障！");
                                            /* socket关闭 */
                                            //                                    if(cDevS.instructionsService->m_socketClient->isConnected()){
                                            //                                        cDevS.instructionsService->m_socketClient->closeSocket();
                                            //                                    }

                                            /* 修改设备状态 */
                                            for(int i = 0; i < connectDeviceInfo.size(); i++){
                                                if(cDevS.dev.id == connectDeviceInfo[i].dev.id){
                                                    connectDeviceInfo[i].dev.status = "故障";
                                                    cDevS.dev.status = "故障";
                                                    break;
                                                }
                                            }

                                            /* 运行计时器停止 */
                                            this->runningTimer->stop();

                                            /* 将Tab状态颜色改变 */
                                            emit ExperimentRunUi::sigShowRunningStatus("故障");

                                            /* 停止线程 */
                                            this->runThread->quit();
                                            this->runThread->wait();
                                            return;
                                        }
                                    }
                                    // 反应板二次判定返回值为空
                                    else if(this->runFlag) {
                                        cusMsg->show(this, CMsg::CCritical, "回传失败", "回传信息为空！");
                                        /* 重置时间为null */
                                        ui->expRunStateLabel->setText("已连接");
                                        ui->expRunStateLabel->setStyleSheet("QLabel {color: #1000EB;font-size:16px;font-family: \"Alibaba PuHuiTi\";}");
                                        QDateTime current_date_time =QDateTime::currentDateTime();
                                        QString current_date = current_date_time.toString("yyyy/MM/dd hh:mm:ss.zzz");
                                        /* 渲染故障 */
                                        ui->textEdit_mistake->append(current_date + " 通信失败：反应板回传信息为空");
                                        ui->errorWidget->show();
                                        ui->errMsg->setPlainText("通信失败：反应板回传信息为空");
                                        /* socket关闭 */
                                        //                                if(cDevS.instructionsService->m_socketClient->isConnected()){
                                        //                                    cDevS.instructionsService->m_socketClient->closeSocket();
                                        //                                }

                                        /* 修改设备状态 */
                                        for(int i = 0; i < connectDeviceInfo.size(); i++){
                                            if(cDevS.dev.id == connectDeviceInfo[i].dev.id){
                                                connectDeviceInfo[i].dev.status = "已连接";
                                                cDevS.dev.status = "已连接";
                                                break;
                                            }
                                        }

                                        /* 运行计时器停止 */
                                        this->runningTimer->stop();

                                        /* 将Tab状态颜色改变 */
                                        emit ExperimentRunUi::sigShowRunningStatus("已连接");

                                        /* 停止线程 */
                                        this->runThread->quit();
                                        this->runThread->wait();
                                        return;
                                    }
                                }
                            }
                            // 扩增二次判定失败
                            else if(procedureStringList[2].contains("失败") && this->runFlag){
                                QMessageBox::critical(this, "扩增数据回传", "扩增程序内容回传失败！\n请检查设备是否断线或有其他故障！");
                                /* 重置时间为null */
                                ui->expRunStateLabel->setText("已连接");
                                ui->expRunStateLabel->setStyleSheet("QLabel {color: #1000EB;font-size:16px;font-family: \"Alibaba PuHuiTi\";}");
                                /* 渲染故障 */
                                ui->textEdit_mistake->append("扩增信息回传失败");
                                ui->errorWidget->show();
                                ui->errMsg->setPlainText("扩增信息回传失败");
                                /* socket关闭 */
                                //                        if(cDevS.instructionsService->m_socketClient->isConnected()){
                                //                            cDevS.instructionsService->m_socketClient->closeSocket();
                                //                        }

                                /* 修改设备状态 */
                                for(int i = 0; i < connectDeviceInfo.size(); i++){
                                    if(cDevS.dev.id == connectDeviceInfo[i].dev.id){
                                        connectDeviceInfo[i].dev.status = "已连接";
                                        cDevS.dev.status = "已连接";
                                        break;
                                    }
                                }

                                /* 运行计时器停止 */
                                this->runningTimer->stop();

                                /* 将Tab状态颜色改变 */
                                emit ExperimentRunUi::sigShowRunningStatus("已连接");

                                /* 停止线程 */
                                this->runThread->quit();
                                this->runThread->wait();
                                return;
                            }
                            // 扩增二次判定故障
                            else if(this->runFlag) {
                                /* 强制跳转到扩增曲线页 */
                                ui->runningTimeTab->setCurrentIndex(1);
                                ui->expRunStateLabel->setText("故障");
                                ui->expRunStateLabel->setStyleSheet("QLabel {color: #B60000;font-size:16px;font-family: \"Alibaba PuHuiTi\";}");
                                /* 渲染故障 */
                                ui->textEdit_mistake->append(procedureStringList[2]);
                                ui->errorWidget->show();
                                ui->errMsg->setPlainText(procedureStringList[2]);
                                cusMsg->show(this, CMsg::CCritical, "错误", "设备故障！");
                                /* socket关闭 */
                                //                        if(cDevS.instructionsService->m_socketClient->isConnected()){
                                //                            cDevS.instructionsService->m_socketClient->closeSocket();
                                //                        }

                                /* 修改设备状态 */
                                for(int i = 0; i < connectDeviceInfo.size(); i++){
                                    if(cDevS.dev.id == connectDeviceInfo[i].dev.id){
                                        connectDeviceInfo[i].dev.status = "故障";
                                        cDevS.dev.status = "故障";
                                        break;
                                    }
                                }

                                /* 运行计时器停止 */
                                this->runningTimer->stop();

                                /* 将Tab状态颜色改变 */
                                emit ExperimentRunUi::sigShowRunningStatus("故障");

                                /* 停止线程 */
                                this->runThread->quit();
                                this->runThread->wait();
                                return;
                            }
                        }
                        // 扩增二次判定返回值为空
                        else if(this->runFlag) {
                            cusMsg->show(this, CMsg::CCritical, "回传失败", "回传信息为空！");
                            /* 重置时间为null */
                            ui->expRunStateLabel->setText("已连接");
                            ui->expRunStateLabel->setStyleSheet("QLabel {color: #1000EB;font-size:16px;font-family: \"Alibaba PuHuiTi\";}");
                            QDateTime current_date_time =QDateTime::currentDateTime();
                            QString current_date = current_date_time.toString("yyyy/MM/dd hh:mm:ss.zzz");
                            /* 渲染故障 */
                            ui->textEdit_mistake->append(current_date + " 通信失败：扩增回传信息为空");
                            ui->errorWidget->show();
                            ui->errMsg->setPlainText("通信失败：扩增信息回传为空");
                            /* socket关闭 */
                            //                    if(cDevS.instructionsService->m_socketClient->isConnected()){
                            //                        cDevS.instructionsService->m_socketClient->closeSocket();
                            //                    }

                            /* 修改设备状态 */
                            for(int i = 0; i < connectDeviceInfo.size(); i++){
                                if(cDevS.dev.id == connectDeviceInfo[i].dev.id){
                                    connectDeviceInfo[i].dev.status = "已连接";
                                    cDevS.dev.status = "已连接";
                                    break;
                                }
                            }

                            /* 运行计时器停止 */
                            this->runningTimer->stop();

                            /* 将Tab状态颜色改变 */
                            emit ExperimentRunUi::sigShowRunningStatus("已连接");

                            /* 停止线程 */
                            this->runThread->quit();
                            this->runThread->wait();
                            return;
                        }
                    }
                    // 扩增一次判定故障
                    else if(this->runFlag) {
                        /* 强制跳转到扩增曲线页 */
                        ui->runningTimeTab->setCurrentIndex(1);
                        ui->expRunStateLabel->setText("故障");
                        ui->expRunStateLabel->setStyleSheet("QLabel {color: #B60000;font-size:16px;font-family: \"Alibaba PuHuiTi\";}");
                        /* 渲染故障 */
                        ui->textEdit_mistake->append(procedureStringList[2]);
                        ui->errorWidget->show();
                        ui->errMsg->setPlainText(procedureStringList[2]);
                        cusMsg->show(this, CMsg::CCritical, "错误", "设备故障！");
                        /* socket关闭 */
                        //                if(cDevS.instructionsService->m_socketClient->isConnected()){
                        //                    cDevS.instructionsService->m_socketClient->closeSocket();
                        //                }

                        /* 修改设备状态 */
                        for(int i = 0; i < connectDeviceInfo.size(); i++){
                            if(cDevS.dev.id == connectDeviceInfo[i].dev.id){
                                connectDeviceInfo[i].dev.status = "故障";
                                cDevS.dev.status = "故障";
                                break;
                            }
                        }

                        /* 运行计时器停止 */
                        this->runningTimer->stop();

                        /* 将Tab状态颜色改变 */
                        emit ExperimentRunUi::sigShowRunningStatus("故障");

                        /* 停止线程 */
                        this->runThread->quit();
                        this->runThread->wait();
                        return;
                    }
                }
                // 扩增第一次判定返回值为空
                else if(this->runFlag) {
                    // 扩增二次判断
                    procedureStringList = this->procedureCallback(cDevS, procedureData);
                    // 扩增二次判断返回值不为空
                    if(procedureStringList.size() != 0 && this->runFlag){
                        // 扩增二次判断成功
                        if(procedureStringList[2].contains("成功") && this->runFlag){
                            // 反应板一次判定
                            reactionPlateStringList = reactionPlateCallback(cDevS, reactionPlateData);
                            // 反应板一次判定不为空
                            if(reactionPlateStringList.size() != 0 && this->runFlag){
                                // 反应板一次判断成功
                                if(reactionPlateStringList[2].contains("成功") && this->runFlag){
                                    /* 线程启动 */
                                    this->runThread->start();
                                }
                                // 反应板一次判断失败
                                else if(reactionPlateStringList[2].contains("失败") && this->runFlag) {
                                    // 反应板二次判断
                                    reactionPlateStringList = reactionPlateCallback(cDevS, reactionPlateData);
                                    // 反应板二次判断不为空
                                    if(reactionPlateStringList.size()  != 0 && this->runFlag){
                                        // 反应板二次判断成功
                                        if(reactionPlateStringList[2].contains("成功") && this->runFlag){
                                            /* 线程启动 */
                                            this->runThread->start();
                                        }
                                        // 反应板二次判断失败
                                        else if(reactionPlateStringList[2].contains("失败") && this->runFlag){
                                            cusMsg->show(this, CMsg::CCritical, "反应板数据回传", "反应板内容回传失败！"
                                                                                           "请检查设备是否断线或有其他故障！");
                                            /* 重置时间为null */
                                            ui->expRunStateLabel->setText("已连接");
                                            ui->expRunStateLabel->setStyleSheet("QLabel {color: #1000EB;font-size:16px;font-family: \"Alibaba PuHuiTi\";}");
                                            /* 渲染故障 */
                                            ui->textEdit_mistake->append("反应板回传信息是失败");
                                            ui->errorWidget->show();
                                            ui->errMsg->setPlainText("反应板回传信息是失败");
                                            /* socket关闭 */
                                            //                                    if(cDevS.instructionsService->m_socketClient->isConnected()){
                                            //                                        cDevS.instructionsService->m_socketClient->closeSocket();
                                            //                                    }

                                            /* 修改设备状态 */
                                            for(int i = 0; i < connectDeviceInfo.size(); i++){
                                                if(cDevS.dev.id == connectDeviceInfo[i].dev.id){
                                                    connectDeviceInfo[i].dev.status = "已连接";
                                                    cDevS.dev.status = "已连接";
                                                    break;
                                                }
                                            }

                                            /* 运行计时器停止 */
                                            this->runningTimer->stop();

                                            /* 将Tab状态颜色改变 */
                                            emit ExperimentRunUi::sigShowRunningStatus("已连接");

                                            /* 停止线程 */
                                            this->runThread->quit();
                                            this->runThread->wait();
                                            return;
                                        }
                                        // 反应板二次判断故障
                                        else if(this->runFlag) {
                                            /* 强制跳转到扩增曲线页 */
                                            ui->runningTimeTab->setCurrentIndex(1);
                                            ui->expRunStateLabel->setText("故障");
                                            ui->expRunStateLabel->setStyleSheet("QLabel {color: #B60000;font-size:16px;font-family: \"Alibaba PuHuiTi\";}");
                                            /* 渲染故障 */
                                            ui->textEdit_mistake->append(reactionPlateStringList[2]);
                                            ui->errorWidget->show();
                                            ui->errMsg->setPlainText(reactionPlateStringList[2]);
                                            cusMsg->show(this, CMsg::CCritical, "错误", "设备故障！");
                                            /* socket关闭 */
                                            //                                    if(cDevS.instructionsService->m_socketClient->isConnected()){
                                            //                                        cDevS.instructionsService->m_socketClient->closeSocket();
                                            //                                    }

                                            /* 修改设备状态 */
                                            for(int i = 0; i < connectDeviceInfo.size(); i++){
                                                if(cDevS.dev.id == connectDeviceInfo[i].dev.id){
                                                    connectDeviceInfo[i].dev.status = "故障";
                                                    cDevS.dev.status = "故障";
                                                    break;
                                                }
                                            }

                                            /* 运行计时器停止 */
                                            this->runningTimer->stop();

                                            /* 将Tab状态颜色改变 */
                                            emit ExperimentRunUi::sigShowRunningStatus("故障");

                                            /* 停止线程 */
                                            this->runThread->quit();
                                            this->runThread->wait();
                                            return;
                                        }
                                    }
                                    // 反应板二次判断为空
                                    else if(this->runFlag) {
                                        cusMsg->show(this, CMsg::CCritical, "回传失败", "回传信息为空！");
                                        /* 重置时间为null */
                                        ui->expRunStateLabel->setText("已连接");
                                        ui->expRunStateLabel->setStyleSheet("QLabel {color: #1000EB;font-size:16px;font-family: \"Alibaba PuHuiTi\";}");
                                        QDateTime current_date_time =QDateTime::currentDateTime();
                                        QString current_date = current_date_time.toString("yyyy/MM/dd hh:mm:ss.zzz");
                                        /* 渲染故障 */
                                        ui->textEdit_mistake->append(current_date + " 通信失败：反应板回传信息为空");
                                        ui->errorWidget->show();
                                        ui->errMsg->setPlainText("通信失败：反应板回传信息为空");
                                        /* socket关闭 */
                                        //                                if(cDevS.instructionsService->m_socketClient->isConnected()){
                                        //                                    cDevS.instructionsService->m_socketClient->closeSocket();
                                        //                                }

                                        /* 修改设备状态 */
                                        for(int i = 0; i < connectDeviceInfo.size(); i++){
                                            if(cDevS.dev.id == connectDeviceInfo[i].dev.id){
                                                connectDeviceInfo[i].dev.status = "已连接";
                                                cDevS.dev.status = "已连接";
                                                break;
                                            }
                                        }

                                        /* 运行计时器停止 */
                                        this->runningTimer->stop();

                                        /* 将Tab状态颜色改变 */
                                        emit ExperimentRunUi::sigShowRunningStatus("已连接");

                                        /* 停止线程 */
                                        this->runThread->quit();
                                        this->runThread->wait();
                                        return;
                                    }
                                }
                                // 反应板一次判断故障
                                else if(this->runFlag){
                                    /* 强制跳转到扩增曲线页 */
                                    ui->runningTimeTab->setCurrentIndex(1);
                                    ui->expRunStateLabel->setText("故障");
                                    ui->expRunStateLabel->setStyleSheet("QLabel {color: #B60000;font-size:16px;font-family: \"Alibaba PuHuiTi\";}");
                                    /* 渲染故障 */
                                    ui->textEdit_mistake->append(reactionPlateStringList[2]);
                                    ui->errorWidget->show();
                                    ui->errMsg->setPlainText(reactionPlateStringList[2]);
                                    cusMsg->show(this, CMsg::CCritical, "错误", "设备故障！");
                                    /* socket关闭 */
                                    //                            if(cDevS.instructionsService->m_socketClient->isConnected()){
                                    //                                cDevS.instructionsService->m_socketClient->closeSocket();
                                    //                            }

                                    /* 修改设备状态 */
                                    for(int i = 0; i < connectDeviceInfo.size(); i++){
                                        if(cDevS.dev.id == connectDeviceInfo[i].dev.id){
                                            connectDeviceInfo[i].dev.status = "故障";
                                            cDevS.dev.status = "故障";
                                            break;
                                        }
                                    }

                                    /* 运行计时器停止 */
                                    this->runningTimer->stop();

                                    /* 将Tab状态颜色改变 */
                                    emit ExperimentRunUi::sigShowRunningStatus("故障");

                                    /* 停止线程 */
                                    this->runThread->quit();
                                    this->runThread->wait();
                                    return;
                                }
                            }
                            // 反应板一次判定为空
                            else if(this->runFlag){
                                // 反应板二次判断
                                reactionPlateStringList = reactionPlateCallback(cDevS, reactionPlateData);
                                // 反应板二次判断不为空
                                if(reactionPlateStringList.size() != 0 && this->runFlag){
                                    // 反应板二次判断成功
                                    if(reactionPlateStringList[2].contains("成功") && this->runFlag){
                                        /* 线程启动 */
                                        this->runThread->start();
                                    }
                                    // 反应板二次判断失败
                                    else if(reactionPlateStringList[2].contains("失败") && this->runFlag){
                                        cusMsg->show(this, CMsg::CCritical, "反应板数据回传", "反应板内容回传失败！"
                                                                                       "请检查设备是否断线或有其他故障！");
                                        /* 重置时间为null */
                                        ui->expRunStateLabel->setText("已连接");
                                        ui->expRunStateLabel->setStyleSheet("QLabel {color: #1000EB;font-size:16px;font-family: \"Alibaba PuHuiTi\";}");
                                        /* 渲染故障 */
                                        ui->textEdit_mistake->append("反应板回传信息失败");
                                        ui->errorWidget->show();
                                        ui->errMsg->setPlainText("反应板回传信息失败");
                                        /* socket关闭 */
                                        //                                if(cDevS.instructionsService->m_socketClient->isConnected()){
                                        //                                    cDevS.instructionsService->m_socketClient->closeSocket();
                                        //                                }

                                        /* 修改设备状态 */
                                        for(int i = 0; i < connectDeviceInfo.size(); i++){
                                            if(cDevS.dev.id == connectDeviceInfo[i].dev.id){
                                                connectDeviceInfo[i].dev.status = "已连接";
                                                cDevS.dev.status = "已连接";
                                                break;
                                            }
                                        }

                                        /* 运行计时器停止 */
                                        this->runningTimer->stop();

                                        /* 将Tab状态颜色改变 */
                                        emit ExperimentRunUi::sigShowRunningStatus("已连接");

                                        /* 停止线程 */
                                        this->runThread->quit();
                                        this->runThread->wait();
                                        return;
                                    }
                                    // 反应板二次判断故障
                                    else if(this->runFlag){
                                        /* 强制跳转到扩增曲线页 */
                                        ui->runningTimeTab->setCurrentIndex(1);
                                        ui->expRunStateLabel->setText("故障");
                                        ui->expRunStateLabel->setStyleSheet("QLabel {color: #B60000;font-size:16px;font-family: \"Alibaba PuHuiTi\";}");
                                        /* 渲染故障 */
                                        ui->textEdit_mistake->append(reactionPlateStringList[2]);
                                        ui->errorWidget->show();
                                        ui->errMsg->setPlainText(reactionPlateStringList[2]);
                                        cusMsg->show(this, CMsg::CCritical, "错误", "设备故障！");
                                        /* socket关闭 */
                                        //                                if(cDevS.instructionsService->m_socketClient->isConnected()){
                                        //                                    cDevS.instructionsService->m_socketClient->closeSocket();
                                        //                                }

                                        /* 修改设备状态 */
                                        for(int i = 0; i < connectDeviceInfo.size(); i++){
                                            if(cDevS.dev.id == connectDeviceInfo[i].dev.id){
                                                connectDeviceInfo[i].dev.status = "故障";
                                                cDevS.dev.status = "故障";
                                                break;
                                            }
                                        }

                                        /* 运行计时器停止 */
                                        this->runningTimer->stop();

                                        /* 将Tab状态颜色改变 */
                                        emit ExperimentRunUi::sigShowRunningStatus("故障");

                                        /* 停止线程 */
                                        this->runThread->quit();
                                        this->runThread->wait();
                                        return;
                                    }
                                }
                                // 反应板二次判断为空
                                else if(this->runFlag){
                                    cusMsg->show(this, CMsg::CCritical, "回传失败", "回传信息为空！");
                                    /* 重置时间为null */
                                    ui->expRunStateLabel->setText("已连接");
                                    ui->expRunStateLabel->setStyleSheet("QLabel {color: #1000EB;font-size:16px;font-family: \"Alibaba PuHuiTi\";}");
                                    QDateTime current_date_time =QDateTime::currentDateTime();
                                    QString current_date = current_date_time.toString("yyyy/MM/dd hh:mm:ss.zzz");
                                    /* 渲染故障 */
                                    ui->textEdit_mistake->append(current_date + " 通信失败：反应板回传信息为空");
                                    ui->errorWidget->show();
                                    ui->errMsg->setPlainText("通信失败：反应板回传信息为空");
                                    /* socket关闭 */
                                    //                            if(cDevS.instructionsService->m_socketClient->isConnected()){
                                    //                                cDevS.instructionsService->m_socketClient->closeSocket();
                                    //                            }

                                    /* 修改设备状态 */
                                    for(int i = 0; i < connectDeviceInfo.size(); i++){
                                        if(cDevS.dev.id == connectDeviceInfo[i].dev.id){
                                            connectDeviceInfo[i].dev.status = "已连接";
                                            cDevS.dev.status = "已连接";
                                            break;
                                        }
                                    }

                                    /* 运行计时器停止 */
                                    this->runningTimer->stop();

                                    /* 将Tab状态颜色改变 */
                                    emit ExperimentRunUi::sigShowRunningStatus("已连接");

                                    /* 停止线程 */
                                    this->runThread->quit();
                                    this->runThread->wait();
                                    return;
                                }
                            }
                        }
                        // 扩增二次判定失败
                        else if(procedureStringList[2].contains("失败") && this->runFlag){
                            cusMsg->show(this, CMsg::CCritical, "反应板数据回传", "反应板内容回传失败！"
                                                                           "请检查设备是否断线或有其他故障！");
                            /* 重置时间为null */
                            ui->expRunStateLabel->setText("已连接");
                            ui->expRunStateLabel->setStyleSheet("QLabel {color: #1000EB;font-size:16px;font-family: \"Alibaba PuHuiTi\";}");
                            /* 渲染故障 */
                            ui->textEdit_mistake->append("扩增回传数据失败");
                            ui->errorWidget->show();
                            ui->errMsg->setPlainText("扩增回传数据失败");
                            /* socket关闭 */
                            //                    if(cDevS.instructionsService->m_socketClient->isConnected()){
                            //                        cDevS.instructionsService->m_socketClient->closeSocket();
                            //                    }

                            /* 修改设备状态 */
                            for(int i = 0; i < connectDeviceInfo.size(); i++){
                                if(cDevS.dev.id == connectDeviceInfo[i].dev.id){
                                    connectDeviceInfo[i].dev.status = "已连接";
                                    cDevS.dev.status = "已连接";
                                    break;
                                }
                            }

                            /* 运行计时器停止 */
                            this->runningTimer->stop();

                            /* 将Tab状态颜色改变 */
                            emit ExperimentRunUi::sigShowRunningStatus("已连接");

                            /* 停止线程 */
                            this->runThread->quit();
                            this->runThread->wait();
                            return;
                        }
                        // 扩增二次判定故障
                        else if(this->runFlag) {
                            /* 强制跳转到扩增曲线页 */
                            ui->runningTimeTab->setCurrentIndex(1);
                            ui->expRunStateLabel->setText("故障");
                            ui->expRunStateLabel->setStyleSheet("QLabel {color: #B60000;font-size:16px;font-family: \"Alibaba PuHuiTi\";}");
                            /* 渲染故障 */
                            ui->textEdit_mistake->append(procedureStringList[2]);
                            ui->errorWidget->show();
                            ui->errMsg->setPlainText(procedureStringList[2]);
                            cusMsg->show(this, CMsg::CCritical, "错误", "设备故障！");
                            /* socket关闭 */
                            //                    if(cDevS.instructionsService->m_socketClient->isConnected()){
                            //                        cDevS.instructionsService->m_socketClient->closeSocket();
                            //                    }

                            /* 修改设备状态 */
                            for(int i = 0; i < connectDeviceInfo.size(); i++){
                                if(cDevS.dev.id == connectDeviceInfo[i].dev.id){
                                    connectDeviceInfo[i].dev.status = "故障";
                                    cDevS.dev.status = "故障";
                                    break;
                                }
                            }

                            /* 运行计时器停止 */
                            this->runningTimer->stop();

                            /* 将Tab状态颜色改变 */
                            emit ExperimentRunUi::sigShowRunningStatus("故障");

                            /* 停止线程 */
                            this->runThread->quit();
                            this->runThread->wait();
                            return;
                        }
                    }
                    // 扩增二次判定返回值为空
                    else if(this->runFlag) {
                        cusMsg->show(this, CMsg::CCritical, "回传失败", "回传信息为空！");
                        /* 重置时间为null */
                        ui->expRunStateLabel->setText("已连接");
                        ui->expRunStateLabel->setStyleSheet("QLabel {color: #1000EB;font-size:16px;font-family: \"Alibaba PuHuiTi\";}");
                        QDateTime current_date_time =QDateTime::currentDateTime();
                        QString current_date = current_date_time.toString("yyyy/MM/dd hh:mm:ss.zzz");
                        /* 渲染故障 */
                        ui->textEdit_mistake->append(current_date + " 通信失败：扩增回传信息为空");
                        ui->errorWidget->show();
                        ui->errMsg->setPlainText("通信失败：扩增回传信息为空");
                        /* socket关闭 */
                        //                if(cDevS.instructionsService->m_socketClient->isConnected()){
                        //                    cDevS.instructionsService->m_socketClient->closeSocket();
                        //                }

                        /* 修改设备状态 */
                        for(int i = 0; i < connectDeviceInfo.size(); i++){
                            if(cDevS.dev.id == connectDeviceInfo[i].dev.id){
                                connectDeviceInfo[i].dev.status = "已连接";
                                cDevS.dev.status = "已连接";
                                break;
                            }
                        }

                        /* 运行计时器停止 */
                        this->runningTimer->stop();

                        /* 将Tab状态颜色改变 */
                        emit ExperimentRunUi::sigShowRunningStatus("已连接");

                        /* 停止线程 */
                        this->runThread->quit();
                        this->runThread->wait();
                        return;
                    }
                }
            }
        }
    }
    else {
        /* 启动按钮恢复绿色 */
        ui->startBtn->setStyleSheet(
                    "font-family: 'Alibaba PuHuiTi';"
                    "color: #fff;"
                    "font-size: 18px;"
                    "font-weight: bold;"
                    "border-radius: 8px;"
                    "background-color: rgb(0, 170, 127);");
    }

}

/* 运行时定时器回调函数 */
void ExperimentRunUi::expRunningTimerCallback(){
    //    try{
    if(this->runFlag){
        /* 发送 init 渲染页面信号 */
        emit ExperimentRunUi::sigInitStyle();
        /* 数据初始化 */

        LOG << "温度休眠" << this->runFlag;

        /* 数据初始化 */
        this->symbolFlag = 0;
        this->yingguangDataList.clear();
        this->wenduDataList.clear();
        wenduDataFlag = "";
        wenduData = "";
        cDevS.instructionsService->wenDuData.clear();
        cDevS.instructionsService->yingguangData.clear();
        cDevS.instructionsService->yingGuangDataList.clear();

        if(this->runFlag){
            /* 发送信号：获取温度数据 */
            emit ExperimentRunUi::sigGetWenduData();
            QThread::msleep(1000); // 线程休眠
            LOG << "温度休眠1";
            /* 获取温度信息 */
            this->wenduDataList = cDevS.instructionsService->getWenduData();

            /* 发送信号：获取并渲染指令 */
            emit ExperimentRunUi::sigRenderZhiLingInfo();

            if(this->wenduDataList.size() != 0 && this->runFlag){
                /* 改变标识 */
                wenduDataFlag = this->wenduDataList[this->wenduDataList.size()-1];
                symbolFlag = wenduDataFlag.toInt();
                /* 写入数据 */
                wenduData = this->wenduDataList[this->wenduDataList.size()-2];
                wenduData = QString::number(convertion->hexToDec(wenduData.toStdString()).toFloat()/10);
                /* 渲染温度样式数据 */
                emit ExperimentRunUi::sigIsTempStyle(wenduData);

                /* 运行结束标志集合 */
                this->currentYinggangSymbolData =
                        convertion->hexToDec(this->wenduDataList[2].toStdString()) +
                        convertion->hexToDec(this->wenduDataList[3].toStdString()) +
                        convertion->hexToDec(this->wenduDataList[4].toStdString()) +
                        convertion->hexToDec(this->wenduDataList[5].toStdString());


                this->currentYinggangSymbolDataSet.insert(currentYinggangSymbolData);

                /* 荧光标志集合初始化 */
                if(this->setSize == 0){
                    /* 存储温度数据 */
                    this->previousStage = this->wenduDataList[2];
                    this->previousNo = this->wenduDataList[3];
                    this->previousStep = this->wenduDataList[4];
                    this->previousCycling = this->wenduDataList[5];
                    this->currentCycling = this->wenduDataList[5].toInt();
                    this->setSize = currentYinggangSymbolDataSet.size();
                    /* 渲染阶段名称 */
                    emit ExperimentRunUi::sigRenderStage(this->previousStage);
                }
                else {
                    /* 集合数据增加 */
                    if(this->setSize != currentYinggangSymbolDataSet.size()){
                        /* 当前步骤 / 阶段结束 */
                        LOG << "当前步骤结束";
                        //                        currentProcedureStepCount++;
                        /* 获取已完成的扩增步骤时间 */
                        emit ExperimentRunUi::sigGetFinishedProcedureTime();

                        QThread::msleep(EXPERIMENT_THREAD_SLEEP_TIME);

                        LOG << "更新数据";

                        /* 更新温度所属数据 */
                        /* 存储温度数据 */
                        this->previousStage = this->wenduDataList[2];
                        this->previousNo = this->wenduDataList[3];
                        this->previousStep = this->wenduDataList[4];
                        this->previousCycling = this->wenduDataList[5];
                        /* 更新集合元素数量 */
                        this->setSize = currentYinggangSymbolDataSet.size();
                        /* 渲染减时间界面样式 */
                        emit ExperimentRunUi::sigMinusTime();
                        /* 渲染阶段名称 */
                        emit ExperimentRunUi::sigRenderStage(this->previousStage);
                    }
                }

            }
            else if(this->runFlag) {
                LOG << "请求失败，重新请求温度数据";
                //                QThread::msleep(2500);
                /* 发送信号：获取温度数据 */
                emit ExperimentRunUi::sigGetWenduData();
                QThread::msleep(1000); // 线程休眠 // 20230804暂改
                LOG << "温度休眠2";
                /* 获取温度信息 */
                this->wenduDataList = cDevS.instructionsService->getWenduData();
                /* 发送信号：获取并渲染指令 */
                emit ExperimentRunUi::sigRenderZhiLingInfo();

                if(this->wenduDataList.size() != 0 && this->runFlag){
                    /* 改变标识 */
                    wenduDataFlag = this->wenduDataList[this->wenduDataList.size()-1];
                    symbolFlag = wenduDataFlag.toInt();
                    /* 渲染数据 */
                    wenduData = this->wenduDataList[this->wenduDataList.size()-2];
                    wenduData = QString::number(convertion->hexToDec(wenduData.toStdString()).toFloat()/10);

                    /* 渲染温度样式数据 */
                    emit ExperimentRunUi::sigIsTempStyle(wenduData);

                    /* 运行结束标志集合 */
                    this->currentYinggangSymbolData =
                            convertion->hexToDec(this->wenduDataList[2].toStdString()) +
                            convertion->hexToDec(this->wenduDataList[3].toStdString()) +
                            convertion->hexToDec(this->wenduDataList[4].toStdString()) +
                            convertion->hexToDec(this->wenduDataList[5].toStdString());

                    this->currentYinggangSymbolDataSet.insert(currentYinggangSymbolData);

                    if(this->setSize == 0){
                        /* 存储温度数据 */
                        this->previousStage = this->wenduDataList[2];
                        this->previousNo = this->wenduDataList[3];
                        this->previousStep = this->wenduDataList[4];
                        this->previousCycling = this->wenduDataList[5];
                        this->currentCycling = this->wenduDataList[5].toInt();
                        this->setSize = currentYinggangSymbolDataSet.size();
                        /* 渲染阶段名称 */
                        emit ExperimentRunUi::sigRenderStage(this->previousStage);
                    }
                    else {
                        /* 集合数据增加 */
                        if(this->setSize != currentYinggangSymbolDataSet.size()){
                            /* 当前步骤 / 阶段结束 */
                            LOG << "当前步骤结束";
                            //                            currentProcedureStepCount++;
                            /* 获取已完成的扩增步骤时间 */
                            emit ExperimentRunUi::sigGetFinishedProcedureTime();

                            QThread::msleep(EXPERIMENT_THREAD_SLEEP_TIME);


                            /* 更新温度所属数据 */
                            /* 存储温度数据 */
                            this->previousStage = this->wenduDataList[2];
                            this->previousNo = this->wenduDataList[3];
                            this->previousStep = this->wenduDataList[4];
                            this->previousCycling = this->wenduDataList[5];
                            /* 更新集合元素数量 */
                            this->setSize = currentYinggangSymbolDataSet.size();
                            /* 渲染减时间界面样式 */
                            emit ExperimentRunUi::sigMinusTime();
                            /* 渲染阶段名称 */
                            emit ExperimentRunUi::sigRenderStage(this->previousStage);
                        }
                    }

                }
                else if(this->runFlag) {
                    this->runFlag = false;
                    /* 回传信息为空时，页面样式设置 */
                    emit ExperimentRunUi::sigIsEmptyStyle("温度数据回传为空");
                    /* socket关闭 */
                    //                    emit ExperimentRunUi::sigCloseDeviceSocket();

                    /* 修改设备状态 */
                    for(int i = 0; i < connectDeviceInfo.size(); i++){
                        if(cDevS.dev.id == connectDeviceInfo[i].dev.id){
                            connectDeviceInfo[i].dev.status = "已连接";
                            cDevS.dev.status = "已连接";
                            break;
                        }
                    }

                    /* 运行计时器停止 */
                    this->runningTimer->stop();

                    /* 将Tab状态颜色改变 */
                    emit ExperimentRunUi::sigShowRunningStatus("已连接");

                    /* 停止线程 */
                    this->runThread->quit();
                    return;
                }
            }
        }
        if(symbolFlag == 6 && this->runFlag){
            /* 发送荧光数据 */
            emit ExperimentRunUi::sigGetYingGuangData();
            QThread::msleep(EXPERIMENT_RUNNING_SLEEP_TIME); // 线程休眠
            /* 获取荧光信息 */
            LOG << "荧光数据";
            this->yingguangDataList = cDevS.instructionsService->getYingGuangData();

            /* 发送信号：获取并渲染指令 */
            emit ExperimentRunUi::sigRenderZhiLingInfo();

            if(this->yingguangDataList.size() != 0){
                /* 循环数增加 */
                for(int i = 0; i < this->yingguangDataList.size(); i++){
                    /* 保存荧光数据 */
                    this->saveYingguangList.append(this->yingguangDataList[i]);
                    this->yingguangData = this->yingguangDataList[i].sample_wells;
                    /* 渲染荧光数据 */
                    this->renderRunningCurve(this->yingguangData);
                    /* 渲染柱状图数据 */
                    emit ExperimentRunUi::sigCurveLabelFilter(this->curBarVisible, "实时");
                }
            }
            else if(this->runFlag) {
                LOG << "请求失败，重新请求荧光数据";
                //                QThread::msleep(2500);
                /* 发送荧光数据 */
                emit ExperimentRunUi::sigGetYingGuangData();
                QThread::msleep(EXPERIMENT_THREAD_SLEEP_TIME); // 线程休眠
                LOG << "荧光数据";
                /* 获取荧光信息 */
                this->yingguangDataList = cDevS.instructionsService->getYingGuangData();
                /* 发送信号：获取并渲染指令 */
                emit ExperimentRunUi::sigRenderZhiLingInfo();

                if(this->yingguangDataList.size() != 0){
                    /* 发送荧光数据 */
                    for(int i = 0; i < this->yingguangDataList.size(); i++){
                        this->saveYingguangList.append(this->yingguangDataList[i]);
                        this->yingguangData = this->yingguangDataList[i].sample_wells;
                        /* 渲染荧光数据 */
                        this->renderRunningCurve(this->yingguangData);
                        /* 渲染柱状图数据 */
                        emit ExperimentRunUi::sigCurveLabelFilter(this->curBarVisible, "实时");
                    }
                }
                else if(this->runFlag) {
                    this->runFlag = false;
                    /* 回传信息为空时，页面样式设置 */
                    emit ExperimentRunUi::sigIsEmptyStyle("荧光数据回传为空");
                    /* socket关闭 */
                    //                    emit ExperimentRunUi::sigCloseDeviceSocket();

                    /* 修改设备状态 */
                    for(int i = 0; i < connectDeviceInfo.size(); i++){
                        if(cDevS.dev.id == connectDeviceInfo[i].dev.id){
                            connectDeviceInfo[i].dev.status = "已连接";
                            cDevS.dev.status = "已连接";
                            break;
                        }
                    }

                    /* 运行计时器停止 */
                    this->runningTimer->stop();

                    /* 将Tab状态颜色改变 */
                    emit ExperimentRunUi::sigShowRunningStatus("已连接");

                    /* 停止线程 */
                    this->runThread->quit();
                    return;
                }
            }
        }
        else if(symbolFlag == 7 && this->runFlag){
            cDevS.instructionsService->guZhangData.clear();
            this->runFlag = false;
            /* 发送故障信号 */
            emit ExperimentRunUi::sigGetGuzhangData();
            QThread::msleep(EXPERIMENT_THREAD_SLEEP_TIME); // 线程休眠q
            QStringList guzhangData = cDevS.instructionsService->getGuZhangData();

            LOG << "guzhangData" << guzhangData;

            /* 发送信号：获取并渲染指令 */
            emit ExperimentRunUi::sigRenderZhiLingInfo();
            /* 渲染故障样式 */
            emit ExperimentRunUi::sigIsErrorStyle(guzhangData);

            /* socket关闭 */
            //            emit ExperimentRunUi::sigCloseDeviceSocket();
            /* 修改设备状态 */
            for(int i = 0; i < connectDeviceInfo.size(); i++){
                if(cDevS.dev.id == connectDeviceInfo[i].dev.id){
                    connectDeviceInfo[i].dev.status = "故障";
                    cDevS.dev.status = "故障";
                    break;
                }
            }

            /* 运行计时器停止 */
            this->runningTimer->stop();

            /* 将Tab状态颜色改变 */
            emit ExperimentRunUi::sigShowRunningStatus("故障");

            /* 停止线程 */
            this->runThread->quit();
            return;
        }
        else if(symbolFlag == 8 && this->runFlag){
            this->runFlag = false;
            /* 如果阶段、编号、步骤、循环数有一个为0 */
            if(convertion->hexToDec(wenduDataList[2].toStdString()) == "0" ||
                    convertion->hexToDec(wenduDataList[3].toStdString()) == "0" ||
                    convertion->hexToDec(wenduDataList[4].toStdString()) == "0" ||
                    convertion->hexToDec(wenduDataList[5].toStdString()) == "0"){
                emit ExperimentRunUi::sigGetZeroSuccess();
            }
            else {
                /* 获取已完成的扩增步骤时间 */
                emit ExperimentRunUi::sigGetFinishedProcedureTime();
                QThread::msleep(EXPERIMENT_THREAD_SLEEP_TIME);

                /* 渲染减时间界面样式 */
                emit ExperimentRunUi::sigMinusTime();
            }

            /* 成功样式渲染 */
            emit ExperimentRunUi::sigIsSuccessStyle();
            /* socket关闭 */
            emit ExperimentRunUi::sigCloseDeviceSocket();
            /* 修改设备状态 */
            for(int i = 0; i < connectDeviceInfo.size(); i++){
                if(cDevS.dev.id == connectDeviceInfo[i].dev.id){
                    connectDeviceInfo[i].dev.status = "已连接";
                    cDevS.dev.status = "已连接";
                    break;
                }
            }

            /* 定时器停止计时 */
            this->runningTimer->stop();

            /* 将Tab状态颜色改变 */
            emit ExperimentRunUi::sigShowRunningStatus("已连接");

            /* 停止线程 */
            this->runThread->quit();
            return;
        }
    }

    QThread::msleep(EXPERIMENT_RUNNING_TIMER_FREQUENCY);
}

/* 实验暂停 */
void ExperimentRunUi::expPauseRunning(){
    LOG << "暂停/启动了";
    /* 启动按钮失效 */
    ui->startBtn->setEnabled(false);
    /* 其他按钮生效 */
    ui->stopBtn->setEnabled(true);

    if(QString::compare(ui->expRunStateLabel->text(), "运行中") == 0){
        this->runFlag = false;
        pauseDialog->show();
    }

    else if(QString::compare(ui->expRunStateLabel->text(), "暂停中") == 0){
        ui->pauseOrContinueBtn->setText("暂停");
        ui->pauseOrContinueBtn->setStyleSheet(
                    "font-family: 'Alibaba PuHuiTi';"
                    "color: #fff;"
                    "font-size: 18px;"
                    "font-weight: bold;"
                    "border-radius: 8px;"
                    "background-color: rgb(255, 170, 0);");
        ui->expRunStateLabel->setText("运行中");
        ui->expRunStateLabel->setStyleSheet("QLabel {color: #086700;font-size:16px;font-family: \"Alibaba PuHuiTi\";}");
        /* 发送开始指令 */
        this->runFlag = true;

        /* 初始化 */
        cDevS.instructionsService->ziJianData.clear();
        /* 判断是否连接 */
        if(!cDevS.instructionsService->m_socketClient->isConnected()){
            cDevS.instructionsService->establishConnection(cDevS.dev.ip, cDevS.dev.port.toInt());
        }
        /* 发送继续指令 */
        cDevS.instructionsService->sendContinue(cDevS.dev.id, id);
        emit ExperimentRunUi::sigRenderZhiLingInfo();
        this->sleep(EXPERIMENT_RUNNING_SLEEP_TIME);
        /* 获取停止时数据 */
        /* 发送信号：获取并渲染指令 */
        emit ExperimentRunUi::sigRenderZhiLingInfo();
        /* 不为空 */
        if(cDevS.instructionsService->ziJianData.size() != 0)
        {
            /* 初始化 */
            cDevS.instructionsService->ziJianData.clear();
            LOG << "关闭动态休眠";
            /* 开始计时器 */
            this->runningTimer->start(1000);
            /* 将Tab状态颜色改变 */
            emit ExperimentRunUi::sigShowRunningStatus("运行");
            /* 开始线程 */
            this->runThread->start();
        }
        /* 数据为空 */
        else {
            /* 判断是否连接 */
            if(!cDevS.instructionsService->m_socketClient->isConnected()){
                cDevS.instructionsService->establishConnection(cDevS.dev.ip, cDevS.dev.port.toInt());
            }
            /* 发送继续指令 */
            cDevS.instructionsService->sendContinue(cDevS.dev.id, id);
            emit ExperimentRunUi::sigRenderZhiLingInfo();
            this->sleep(EXPERIMENT_RUNNING_SLEEP_TIME);
            /* 获取继续时数据 */
            /* 发送信号：获取并渲染指令 */
            emit ExperimentRunUi::sigRenderZhiLingInfo();

            if(cDevS.instructionsService->ziJianData.size() != 0){
                /* 初始化 */
                cDevS.instructionsService->ziJianData.clear();
                LOG << "关闭动态休眠";
                /* 开始计时器 */
                this->runningTimer->start(1000);
                /* 将Tab状态颜色改变 */
                emit ExperimentRunUi::sigShowRunningStatus("运行");
                /* 开始线程 */
                this->runThread->start();
            }
            /* 二次判空 */
            else {
                /* 显示样式 */
                emit ExperimentRunUi::sigIsEmptyStyle("继续回传数据为空");
                /* 初始化 */
                cDevS.instructionsService->ziJianData.clear();

                /* 运行计时器停止 */
                this->runningTimer->stop();

                /* 将Tab状态颜色改变 */
                emit ExperimentRunUi::sigShowRunningStatus("已连接");

                /* 停止线程 */
                this->runFlag = false;
                this->runThread->quit();
            }
        }
    }
}

/* 实验停止 */
void ExperimentRunUi::expStopRunning(){
    if(QMessageBox::Yes == cusMsg->show(this, CMsg::CQuestion, "实验停止", "是否停止实验？")){
        LOG << "停止了";
        /* 渲染停止时间 */
        /* 获取当前日期时间 */
        QDateTime expTime = QDateTime::currentDateTime();
        /* 转QString */
        QString expStringDate = expTime.toString("yyyy-MM-dd hhmmss");

        ui->labelInfo4->setText(expStringDate);
        this->runFlag = false;

        /* 停止：实验结束标识位改变 */
        //        this->experimentService->updateStateEnd(this->id.toInt());

        /* 初始化 */
        cDevS.instructionsService->ziJianData.clear();
        /* 判断是否连接 */
        if(!cDevS.instructionsService->m_socketClient->isConnected()){
            cDevS.instructionsService->establishConnection(cDevS.dev.ip, cDevS.dev.port.toInt());
        }
        /* 发送停止指令 */
        cDevS.instructionsService->sendClose(cDevS.dev.id, id);
        /* 发送信号：获取并渲染指令 */
        emit ExperimentRunUi::sigRenderZhiLingInfo();
        this->sleep(EXPERIMENT_RUNNING_SLEEP_TIME);
        /* 发送信号：获取并渲染指令 */
        emit ExperimentRunUi::sigRenderZhiLingInfo();
        /* 获取停止时数据 */
        /* 不为空 */
        if(cDevS.instructionsService->ziJianData.size() != 0)
        {
            /* 关闭链接 */
            if(cDevS.instructionsService->m_socketClient->isConnected()){
                cDevS.instructionsService->m_socketClient->closeSocket();
            }

            /* 实验停止提示框 */
            cusMsg->show(this, CMsg::CInformation, "停止实验", "实验停止！");

            /* 初始化 */
            cDevS.instructionsService->ziJianData.clear();
        }
        /* 数据为空 */
        else {
            /* 判断是否连接 */
            if(!cDevS.instructionsService->m_socketClient->isConnected()){
                cDevS.instructionsService->establishConnection(cDevS.dev.ip, cDevS.dev.port.toInt());
            }
            /* 发送停止指令 */
            cDevS.instructionsService->sendClose(cDevS.dev.id, id);
            /* 发送信号：获取并渲染指令 */
            emit ExperimentRunUi::sigRenderZhiLingInfo();

            this->sleep(EXPERIMENT_RUNNING_SLEEP_TIME);
            /* 发送信号：获取并渲染指令 */
            emit ExperimentRunUi::sigRenderZhiLingInfo();

            /* 获取停止时数据 */
            if(cDevS.instructionsService->ziJianData.size() != 0){
                /* 关闭链接 */
                if(cDevS.instructionsService->m_socketClient->isConnected()){
                    cDevS.instructionsService->m_socketClient->closeSocket();
                }

                /* 实验停止提示框 */
                cusMsg->show(this, CMsg::CInformation, "停止实验", "实验停止！");

                /* 初始化 */
                cDevS.instructionsService->ziJianData.clear();
            }
            /* 二次判空 */
            else {
                /* socket关闭 */
                if(cDevS.instructionsService->m_socketClient->isConnected()){
                    cDevS.instructionsService->m_socketClient->closeSocket();
                }
                /* 显示样式 */
                emit ExperimentRunUi::sigIsEmptyStyle("停止回传数据为空");
                /* 初始化 */
                cDevS.instructionsService->ziJianData.clear();
            }
        }

        /* 停止和继续按钮失效 */
        ui->stopBtn->setEnabled(false);
        ui->pauseOrContinueBtn->setEnabled(false);
        ui->pauseOrContinueBtn->setText("暂停");
        /* 其他按钮生效 */
        ui->startBtn->setEnabled(true);

        /* 定时器停止计时 */
        this->runningTimer->stop();

        /* 错误框隐藏 */
        ui->errorWidget->hide();

        ui->pauseOrContinueBtn->setStyleSheet(
                    "font-family: 'Alibaba PuHuiTi';"
                    "color: #fff;"
                    "font-size: 18px;"
                    "font-weight: bold;"
                    "border-radius: 8px;"
                    "background-color: #a2a2a2;");
        ui->startBtn->setStyleSheet(
                    "font-family: 'Alibaba PuHuiTi';"
                    "color: #fff;"
                    "font-size: 18px;"
                    "font-weight: bold;"
                    "border-radius: 8px;"
                    "background-color: rgb(0,170,127);");
        ui->stopBtn->setStyleSheet(
                    "font-family: 'Alibaba PuHuiTi';"
                    "color: #fff;"
                    "font-size: 18px;"
                    "font-weight: bold;"
                    "border-radius: 8px;"
                    "background-color: #a2a2a2;");

        /* 如果不为故障，则改为已连接 */
        if(cDevS.dev.status != "故障"){
            cDevS.dev.status = "已连接";
            for(int i = 0; i < connectDeviceInfo.size(); i++){
                if(cDevS.dev.id == connectDeviceInfo[i].dev.id){
                    connectDeviceInfo[i].dev.status = "已连接";
                    break;
                }
            }
            ui->expRunStateLabel->setText(cDevS.dev.status);
            ui->expRunStateLabel->setStyleSheet("QLabel {font-size:16px;font-family: \"Alibaba PuHuiTi\";}");
            /* 将Tab状态颜色改变 */
            emit ExperimentRunUi::sigShowRunningStatus("已连接");
        }

        // 释放日志对象
        cDevS.instructionsService->m_socketClient->qpcrLog->release();

        /* 停止线程 */
        this->runThread->quit();

        {
            /* 渲染实验恢复页面实验列表 */
            emit ExperimentRunUi::renderRestoreList();

            /* 发送信号：获取并渲染指令 */
            emit ExperimentRunUi::sigRenderZhiLingInfo();
            /* 跳转下一页 */
            this->nextCallback();
            /* 发送信号：刷新活跃设备列表 */
            emit ExperimentRunUi::updateInactiveDeviceList();
            /* 渲染结果曲线 */
//        todo 停止不渲染结果曲线    emit ExperimentRunUi::successRenderResultCurve();
        }
    }
}

/* 颜色显示器控制函数 */
void ExperimentRunUi::colorControlFunction(){
    // 根据图例选择框，判断图例和曲线颜色控制样式
    if(ui->legendSelector->currentText() == "图谱"){ // 控制曲线图例
        (this->lineVisibleList["1"] == true) ? (this->famVisible = true) :
                                               (this->famVisible = false); // fam
        (this->lineVisibleList["2"] == true) ? (this->vicVisible = true) :
                                               (this->vicVisible = false); // vic
        (this->lineVisibleList["3"] == true) ? (this->roxVisible = true) :
                                               (this->roxVisible = false); // rox
        (this->lineVisibleList["4"] == true) ? (this->cy5Visible = true) :
                                               (this->cy5Visible = false); // cy5
    }else if(ui->legendSelector->currentText() == "实时"){ // 控制柱状图图例
        switch (this->curBarVisible.toInt()) {
        case 1: // fam
            this->famVisible = true;
            this->vicVisible = false;
            this->roxVisible = false;
            this->cy5Visible = false;
            break;
        case 2: // vic
            this->famVisible = false;
            this->vicVisible = true;
            this->roxVisible = false;
            this->cy5Visible = false;
            break;
        case 3: // rox
            this->famVisible = false;
            this->vicVisible = false;
            this->roxVisible = true;
            this->cy5Visible = false;
            break;
        case 4: // cy5
            this->famVisible = false;
            this->vicVisible = false;
            this->roxVisible = false;
            this->cy5Visible = true;
            break;
        }
    }
}

/* 渲染图例样式 */
void ExperimentRunUi::renderLegendStyle(){
    // 初始化：将图例都变灰
    QString initStyleSheet = "QPushButton {min-width: 10px; max-width: 10px; min-height: 10px; max-height: 10px; border: 1px solid rgba(0,0,0,.5);" "background-color: rgba(0,0,0,.3);}";
    ui->famBtn->setStyleSheet(initStyleSheet);
    ui->vicBtn->setStyleSheet(initStyleSheet);
    ui->roxBtn->setStyleSheet(initStyleSheet);
    ui->cy5Btn->setStyleSheet(initStyleSheet);

    // 渲染四个可见图例颜色
    // fam
    if(this->famVisible){
        if(targetLegendColor1 != ""){
            /* 改变图例样式 */
            QString styleSheet = "QPushButton {min-width: 10px; max-width: 10px; min-height: 10px; max-height: 10px; border: 1px solid rgba(0,0,0,.5);" "background-color: rgb(" + targetLegendColor1 + ");}";
            ui->famBtn->setStyleSheet(styleSheet);
        }
    }else {
        /* 改变图例样式 */
        QString styleSheet = "QPushButton {min-width: 10px; max-width: 10px; min-height: 10px; max-height: 10px; border: 1px solid rgba(0,0,0,.5);" "background-color: rgba(0,0,0,.3);}";
        ui->famBtn->setStyleSheet(styleSheet);
    }

    // vic
    if(this->vicVisible){
        if(targetLegendColor2 != ""){
            /* 改变图例样式 */
            QString styleSheet = "QPushButton {min-width: 10px; max-width: 10px; min-height: 10px; max-height: 10px; border: 1px solid rgba(0,0,0,.5);" "background-color: rgb(" + targetLegendColor2 + ");}";
            ui->vicBtn->setStyleSheet(styleSheet);
        }
    }else {
        /* 改变图例样式 */
        QString styleSheet = "QPushButton {min-width: 10px; max-width: 10px; min-height: 10px; max-height: 10px; border: 1px solid rgba(0,0,0,.5);" "background-color: rgba(0,0,0,.3);}";
        ui->vicBtn->setStyleSheet(styleSheet);
    }

    // rox
    if(this->roxVisible){
        if(targetLegendColor3 != ""){
            /* 改变图例样式 */
            QString styleSheet = "QPushButton {min-width: 10px; max-width: 10px; min-height: 10px; max-height: 10px; border: 1px solid rgba(0,0,0,.5);" "background-color: rgb(" + targetLegendColor3 + ");}";
            ui->roxBtn->setStyleSheet(styleSheet);
        }
    }else {
        /* 改变图例样式 */
        QString styleSheet = "QPushButton {min-width: 10px; max-width: 10px; min-height: 10px; max-height: 10px; border: 1px solid rgba(0,0,0,.5);" "background-color: rgba(0,0,0,.3);}";
        ui->roxBtn->setStyleSheet(styleSheet);
    }

    // cy5
    if(this->cy5Visible){
        if(targetLegendColor4 != ""){
            /* 改变图例样式 */
            QString styleSheet = "QPushButton {min-width: 10px; max-width: 10px; min-height: 10px; max-height: 10px; border: 1px solid rgba(0,0,0,.5);" "background-color: rgb(" + targetLegendColor4 + ");}";
            ui->cy5Btn->setStyleSheet(styleSheet);
        }
    }else {
        /* 改变图例样式 */
        QString styleSheet = "QPushButton {min-width: 10px; max-width: 10px; min-height: 10px; max-height: 10px; border: 1px solid rgba(0,0,0,.5);" "background-color: rgba(0,0,0,.3);}";
        ui->cy5Btn->setStyleSheet(styleSheet);
    }
}

/* 渲染扩增曲线数据样式 */
void ExperimentRunUi::renderLineDataStyle(){
    // 根据四个可见图例，渲染当前可见的荧光曲线
    for(int i = 0; i < 96; i++){
        // fam
        if(this->famVisible){
            if(targetLegendColor1 != ""){
                QStringList colorList1 = targetLegendColor1.split(",");
                famSeriesList[i]->setPen(QPen(QColor(colorList1[0].toInt(), colorList1[1].toInt(), colorList1[2].toInt(), 255), 2, Qt::SolidLine));
                famSeriesList[i]->setColor(QColor(colorList1[0].toInt(), colorList1[1].toInt(), colorList1[2].toInt(), 255));
            }
        }
        else {
            famSeriesList[i]->setPen(QPen(QColor(250, 81, 81, 0), 2, Qt::SolidLine));
            famSeriesList[i]->setColor(QColor(250, 81, 81, 0));
        }


        // vic
        if(this->vicVisible){
            if(targetLegendColor2 != ""){
                QStringList colorList2 = targetLegendColor2.split(",");
                vicSeriesList[i]->setPen(QPen(QColor(colorList2[0].toInt(), colorList2[1].toInt(), colorList2[2].toInt(), 255), 2, Qt::SolidLine));
                vicSeriesList[i]->setColor(QColor(colorList2[0].toInt(), colorList2[1].toInt(), colorList2[2].toInt(), 255));
            }
        }
        else {
            vicSeriesList[i]->setPen(QPen(QColor(0, 181, 120, 0), 2, Qt::SolidLine));
            vicSeriesList[i]->setColor(QColor(0, 181, 120, 0));
        }

        // rox
        if(this->roxVisible){
            if(targetLegendColor3 != ""){
                QStringList colorList3 = targetLegendColor3.split(",");
                roxSeriesList[i]->setPen(QPen(QColor(colorList3[0].toInt(), colorList3[1].toInt(), colorList3[2].toInt(), 255), 2, Qt::SolidLine));
                roxSeriesList[i]->setColor(QColor(colorList3[0].toInt(), colorList3[1].toInt(), colorList3[2].toInt(), 255));
            }
        }
        else {
            roxSeriesList[i]->setPen(QPen(QColor(7, 185, 185, 0), 2, Qt::SolidLine));
            roxSeriesList[i]->setColor(QColor(7, 185, 185, 0));
        }
        // cy5
        if(this->cy5Visible){
            /* 改变曲线颜色 */
            if(targetLegendColor4 != ""){
                QStringList colorList4 = targetLegendColor4.split(",");
                cy5SeriesList[i]->setPen(QPen(QColor(colorList4[0].toInt(), colorList4[1].toInt(), colorList4[2].toInt(), 255), 2, Qt::SolidLine));
                cy5SeriesList[i]->setColor(QColor(colorList4[0].toInt(), colorList4[1].toInt(), colorList4[2].toInt(), 255));
            }
        }
        else {
            cy5SeriesList[i]->setPen(QPen(QColor(138, 56, 245, 0), 2, Qt::SolidLine));
            cy5SeriesList[i]->setColor(QColor(138, 56, 245, 0));
        }
    }

    this->expRunChart->update();
    ui->lineGraphicsView->update();

}

/* 渲染运行曲线 */
void ExperimentRunUi::renderRunningCurve(QList<QHash<QString, QString>> yingGuangData){
    this->xSeries++;
    // 添加到荧光数据列表中
    saveYingguangDataList.append(yingGuangData);

    for(int i = 0; i < yingGuangData.size(); i++){

        /* 判断当前所传荧光数据的反应板值是否为"null"，如果是，则不做处理 */
        /* 判断第i个孔位的第j个位置靶基因的报告基因 */
        int targetCount = sizeof(reactionPlate.targetList[i])/sizeof(Target); // 获取靶基因数量
        for(int j = 0; j < targetCount; j++){ // 获取靶基因，渲染曲线
            if(reactionPlate.targetList[i][j].reporter == "FAM"){
                /* 设置 fam 样本 */
                famSeriesList[i]->append(xSeries, yingGuangData[i]["1"].toInt()); // 设置数据
            }
            else if (reactionPlate.targetList[i][j].reporter == "VIC") {
                vicSeriesList[i]->append(xSeries, yingGuangData[i]["2"].toInt()); // 设置数据
            }
            else if (reactionPlate.targetList[i][j].reporter == "ROX") {
                roxSeriesList[i]->append(xSeries, yingGuangData[i]["3"].toInt()); // 设置数据
            }
            else if (reactionPlate.targetList[i][j].reporter == "CY5") {
                cy5SeriesList[i]->append(xSeries, yingGuangData[i]["4"].toInt()); // 设置数据
            }
            expRunChart->update();
        }
    }
}

/* 渲染柱状图数据样式 */
void ExperimentRunUi::renderBarDataStyle(){
    QStringList colorList; // 颜色数组

    this->barSet->setBrush(QColor(0,0,0,0));

    switch (this->curBarVisible.toInt()) {
    case 1: // fam
        if(targetLegendColor1 != ""){
            colorList = targetLegendColor1.split(",");
        }
        break;
    case 2: // vic
        if(targetLegendColor2 != ""){
            colorList = targetLegendColor2.split(",");
            this->barSet->setBrush(QColor(colorList[0].toInt(), colorList[1].toInt(), colorList[2].toInt()));
        }
        break;
    case 3: // rox
        if(targetLegendColor3 != ""){
            colorList = targetLegendColor3.split(",");
        }
        break;
    case 4: // cy5
        if(targetLegendColor4 != ""){
            colorList = targetLegendColor4.split(",");
        }
        break;
    }
    this->barSet->setBrush(QColor(colorList[0].toInt(), colorList[1].toInt(), colorList[2].toInt())); // 设置柱状图颜色
    this->barSet->setLabelColor(QColor(colorList[0].toInt(), colorList[1].toInt(), colorList[2].toInt())); // 设置标签颜色
}

/* 根据当前荧光曲线数据，渲染柱状图数据 */
void ExperimentRunUi::renderBarData(QList<QHash<QString, QString>> yingguangData){
    // 初始化
    this->barSet->remove(0, this->barSetCount); // 清空柱状图组

    this->renderBarDataStyle(); // 渲染柱状图样式

    // 根据当前柱状图图例所选的何种通道，渲染对应的通道值
    QList<double> dataList; // 荧光数据列表
    int yingguangDataSize = yingguangData.size(); // 荧光数据大小
    QString barFilterCond = ""; // 柱状图过滤条件
    QString barFilterCondNum = this->curBarVisible; // 柱状图过滤条件（数字型）

    // 数据标签操作
    int barUnitWidth = this->expBarChart->geometry().width()/expBarXAxis->count(); // 一个柱状图柱子的单元宽度（向上取整）
    int adaptedFontSize = barUnitWidth / 10; // 最佳适应字体大小：单个柱子宽度除以10再减1
    QFont barFont = this->barSet->labelFont(); // 当前BarSet所使用的的字体大小

    // 根据当前选中的图例，渲染所选中的柱状图数据
    switch (barFilterCondNum.toInt()) {
    case 1: // fam
        barFilterCond = "FAM";
        break;
    case 2: // vic
        barFilterCond = "VIC";
        break;
    case 3: // rox
        barFilterCond = "ROX";
        break;
    case 4: // cy5
        barFilterCond = "CY5";
        break;
    }

    for(int i = 0; i < yingguangDataSize; i++){
        /* 判断当前所传荧光数据的反应板值是否为"null"，如果是，则不做处理 */
        /* 判断第i个孔位的第j个位置靶基因的报告基因 */
        int targetCount = sizeof(reactionPlate.targetList[i])/sizeof(Target); // 获取靶基因数量
        int tarCount = 0; // 靶基因存在计数器：判断如果当前孔位选中了靶基因，但是该孔位并没有当前所选中的靶基因时的判断条件
        bool tarFlag = false; // 选中靶基因添加标志：如果该孔位有选中的靶基因，并添加了数据，则该标识为true，tarCount不工作
        for(int j = 0; j < targetCount; j++){ // 获取靶基因，渲染柱状图数据
            if(this->reactionPlate.targetList[i][j].reporter != "null"){ // 如果当前孔位有靶基因
                tarCount++; // 靶基因计数器加1
                if(this->reactionPlate.targetList[i][j].reporter == barFilterCond){ // 有 孔位选中靶基因
                    dataList << yingguangData[i][barFilterCondNum].toInt(); // 添加数据
                    tarFlag = true; // 靶基因已经添加
                }
            }
        }
        if(!tarFlag && tarCount != 0){
            dataList << 0; // 靶基因有数据，且走到了这里，说明该孔位没有过滤的靶基因，将该孔位的该靶基因数据设为0
        }
    }

    // 处理标签字体
    // 柱子的宽度 取 十位 减 1 + 偏移量，得到实际字体的宽度
    adaptedFontSize = barUnitWidth / 10 + 2;

    LOG << "adaptedFontSize" << adaptedFontSize << barUnitWidth;

    this->barSeries->setLabelsAngle(0); // 将标签旋转为0度

    /* 如果字体大小小于最小字体 */
    if(adaptedFontSize < MIN_BAR_LABEL_FONT){
        adaptedFontSize = MIN_BAR_LABEL_FONT; // 将字体大小设为最小字体大小
        this->barSeries->setLabelsAngle(25); // 并将标签旋转30度
    }
    /* 如果字体大小大于最大字体 */
    else if(adaptedFontSize > MAX_BAR_LABEL_FONT){
        adaptedFontSize = MAX_BAR_LABEL_FONT; // 将字体大小设为最大字体大小
    }

    barFont.setPointSize(adaptedFontSize); // 设置字体大小
    this->barSet->setLabelFont(barFont); // 设置到barset中

    QFont fontsss = this->barSet->labelFont();

    // 向set中添加数据
    this->barSet->append(dataList);
}

/* 曲线过滤函数（图标过滤） */
void ExperimentRunUi::curveLabelFilter(QString filterNum, QString filterType){
    if(filterType == "图谱"){
        this->lineVisibleList[filterNum] = !this->lineVisibleList[filterNum]; // 曲线暂存图例颜色取反
        this->colorControlFunction(); // 颜色控制器函数
        this->renderLineDataStyle(); // 渲染曲线颜色
    }else if(filterType == "实时"){
        this->curBarVisible = filterNum; // 柱状图暂存曲线图例设置
        this->colorControlFunction(); // 颜色控制器函数
        this->renderBarData(this->yingguangData);
    }
    this->renderLegendStyle(); // 渲染图例
}

/* 扩增回调 */
QStringList ExperimentRunUi::procedureCallback(ConnectedDeviceStruct cDevS, QString procedureData){
    /* 建立链接 */
    if(!cDevS.instructionsService->m_socketClient->isConnected()){
        cDevS.instructionsService->establishConnection(cDevS.dev.ip, cDevS.dev.port.toInt());
    }
    cDevS.instructionsService->sendKuozengData(id, procedureData);
    /* 发送信号：获取并渲染指令 */
    emit ExperimentRunUi::sigRenderZhiLingInfo();
    // 2s 休眠
    LOG << "扩增休眠";
    this->sleep(EXPERIMENT_RUNNING_SLEEP_TIME);
    // 获取扩增字符串数组
    QStringList procedureStringList = cDevS.instructionsService->getKuoZengData();
    //    cDevS.instructionsService->m_socketClient->sendZhiLing2Ui();
    /* 发送信号：获取并渲染指令 */
    emit ExperimentRunUi::sigRenderZhiLingInfo();
    if(procedureStringList.size() != 0){
        if(!procedureStringList[2].contains("成功")){
            ui->textEdit_mistake->append(procedureStringList[2]);
        }
    }
    return procedureStringList;
}

/* 反应板回调 */
QStringList ExperimentRunUi::reactionPlateCallback(ConnectedDeviceStruct cDevS, QString reactionPlateData){
    /* 建立链接 */
    if(!cDevS.instructionsService->m_socketClient->isConnected()){
        cDevS.instructionsService->establishConnection(cDevS.dev.ip, cDevS.dev.port.toInt());
    }
    cDevS.instructionsService->sendYangbenData(id, reactionPlateData);
    /* 发送信号：获取并渲染指令 */
    emit ExperimentRunUi::sigRenderZhiLingInfo();
    // 2s 休眠
    LOG << "样本休眠";
    this->sleep(EXPERIMENT_RUNNING_SLEEP_TIME);
    // 获取反应板字符串数组
    QStringList reactionStringList = cDevS.instructionsService->getYangbenData();
    //    cDevS.instructionsService->m_socketClient->sendZhiLing2Ui();
    /* 发送信号：获取并渲染指令 */
    emit ExperimentRunUi::sigRenderZhiLingInfo();
    if(reactionStringList.size() != 0){
        if(!reactionStringList[2].contains("成功")){
            ui->textEdit_mistake->append(reactionStringList[2]);
        }
    }
    return reactionStringList;
}

/* 反应板：从配置文件中读取行列数 */
void ExperimentRunUi::RenderTableRowColumnFromXML(){
    ConfigFileService *configService = new ConfigFileService();
    QString consume = reactionPlate.consumables;
    int* sampleTableRowColumn = configService->getRowAndColByConsumableType(consume);

    LOG << "获取运行页面所需数据" << sampleTableRowColumn[0] << sampleTableRowColumn[1];

    int row = sampleTableRowColumn[0];
    int column = sampleTableRowColumn[1];

    if(row != 8){
        column = 2;
        row = 8;
    }


    ui->expRunTable->clear();
    ui->expRunTable->setVerticalHeaderLabels(QStringList() << "A" << "B" << "C" << "D" << "E" << "F" << "G" << "H");
    for(int m = 0; m < row; m ++){
        for(int n = column; n < 12; n ++){
            QTableWidgetItem *newItem = new QTableWidgetItem();
            newItem->setFlags(newItem->flags() & ~Qt::ItemIsSelectable);
            ui->expRunTable->setItem(m, n, newItem);
            QTableWidgetItem *item = ui->expRunTable->item(m, n);
            item->setFlags(item->flags() & ~Qt::ItemIsEnabled & ~Qt::ItemIsSelectable);
            ui->expRunTable->setColumnHidden(n, true);
        }
    }
    for(int m = 0; m < row; m ++){
        for(int n = 0; n < column; n ++){
            ui->expRunTable->setColumnHidden(n, false);
        }
    }

}

/* 关闭Socket通信 */
void ExperimentRunUi::callbackCloseDeviceSocket(){
    if(cDevS.instructionsService->m_socketClient->isConnected()){
        cDevS.instructionsService->m_socketClient->closeSocket();
    }
}

/* 刚进入循环时，界面样式设置 */
void ExperimentRunUi::callbackInitStyle(){
    /* 停止和暂停按钮生效 */
    ui->pauseOrContinueBtn->setEnabled(true);
    ui->stopBtn->setEnabled(true);
    ui->pauseOrContinueBtn->setStyleSheet(
                "font-family: 'Alibaba PuHuiTi';"
                "color: #fff;"
                "font-size: 18px;"
                "font-weight: bold;"
                "border-radius: 8px;"
                "background-color: rgb(255, 170, 0);");
    ui->stopBtn->setStyleSheet(
                "font-family: 'Alibaba PuHuiTi';"
                "color: #fff;"
                "font-size: 18px;"
                "font-weight: bold;"
                "border-radius: 8px;"
                "background-color: #fe7272;");
}

/* 回传信息为空时，界面样式设置 */
void ExperimentRunUi::callbackIsEmptyStyle(QString text){
    cusMsg->show(this, CMsg::CCritical, "错误", "设备通讯失败！"
                                              "请检查设备是否断线或有其他故障！");
    /* 暂停按钮失效 */
    ui->pauseOrContinueBtn->setEnabled(false);
    /* 改变按钮样式 */
    ui->pauseOrContinueBtn->setStyleSheet(
                "font-family: 'Alibaba PuHuiTi';"
                "color: #fff;"
                "font-size: 18px;"
                "font-weight: bold;"
                "border-radius: 8px;"
                "background-color: #a2a2a2;");
    /* 重置时间为null */
    ui->expRunStateLabel->setText("已连接");
    ui->expRunStateLabel->setStyleSheet("QLabel {color: #1000EB;font-size:16px;font-family: \"Alibaba PuHuiTi\";}");
    /* 渲染故障 */
    QDateTime current_date_time =QDateTime::currentDateTime();
    QString current_date = current_date_time.toString("yyyy/MM/dd hh:mm:ss.zzz");
    /* 渲染故障 */
    ui->textEdit_mistake->append(current_date + " 通信失败：" + text);
    ui->errorWidget->show();
    ui->errMsg->setPlainText(text);
}

/* 回传信息为故障时，界面样式设置 */
void ExperimentRunUi::callbackIsErrorStyle(QStringList guzhangData){
    ui->runningTimeTab->setCurrentIndex(1);
    /* 暂停按钮失效 */
    ui->pauseOrContinueBtn->setEnabled(false);
    /* 改变按钮样式 */
    ui->pauseOrContinueBtn->setStyleSheet(
                "font-family: 'Alibaba PuHuiTi';"
                "color: #fff;"
                "font-size: 18px;"
                "font-weight: bold;"
                "border-radius: 8px;"
                "background-color: #a2a2a2;");
    /* 渲染故障 */
    ui->textEdit_mistake->append(guzhangData[2]);
    ui->errMsg->setPlainText(guzhangData[2]);
    ui->errorWidget->show();
    cusMsg->show(this, CMsg::CCritical, "实验", "设备故障！");

    ui->expRunStateLabel->setText("故障");
    ui->expRunStateLabel->setStyleSheet("QLabel {color: #B60000;font-size:16px;font-family: \"Alibaba PuHuiTi\";}");
}

/* 回传信息为成功时，界面样式设置 */
void ExperimentRunUi::callbackIsSuccessStyle(){
    int minute, second;
    /* 获取当前运行时间 */
    QString currentRunningTime = ui->info_4->text();
    /* 拆分为分钟和秒 */
    if(currentRunningTime != ""){
        QStringList minuteList = currentRunningTime.split("分");
        if(minuteList.size() > 1){
            minute = minuteList[0].toInt();
            QStringList secondList = minuteList[1].split("秒");
            if(secondList.size() != 0){
                second = secondList[0].toInt();
            }
        }
    }
    cusMsg->show(this, CMsg::CInformation,
                 "实验",
                 "实验运行完毕！\n总运行时间为" + QString::number(minute) + "分" + QString::number(second) + "秒");

    /* 实验正常结束：实验结束标识位改变 */
    this->experimentService->updateStateEnd(this->experiment.experiment_id.toInt());
    /* 所有按钮回到初始状态 */
    ui->expRunStateLabel->setText("已连接");
    ui->expRunStateLabel->setStyleSheet("QLabel {color: black;font-size:16px;font-family: \"Alibaba PuHuiTi\";}");
    /* 所有按钮回到初始状态 */
    /* 停止和继续按钮失效 */
    ui->stopBtn->setEnabled(false);
    ui->pauseOrContinueBtn->setEnabled(false);
    ui->pauseOrContinueBtn->setText("暂停");
    /* 其他按钮生效 */
    ui->startBtn->setEnabled(true);
    ui->pauseOrContinueBtn->setStyleSheet(
                "font-family: 'Alibaba PuHuiTi';"
                "color: #fff;"
                "font-size: 18px;"
                "font-weight: bold;"
                "border-radius: 8px;"
                "background-color: #a2a2a2;");
    ui->startBtn->setStyleSheet(
                "font-family: 'Alibaba PuHuiTi';"
                "color: #fff;"
                "font-size: 18px;"
                "font-weight: bold;"
                "border-radius: 8px;"
                "background-color: rgb(0,170,127);");
    ui->stopBtn->setStyleSheet(
                "font-family: 'Alibaba PuHuiTi';"
                "color: #fff;"
                "font-size: 18px;"
                "font-weight: bold;"
                "border-radius: 8px;"
                "background-color: #a2a2a2;");
    /* 释放日志对象 */
    cDevS.instructionsService->m_socketClient->qpcrLog->release();
    /* 跳转下一页 */
    this->nextCallback();
    /* 发送信号：刷新活跃设备列表 */
    emit ExperimentRunUi::updateInactiveDeviceList();
    /* 发送信号：更新实验实验恢复列表实验设备 */
    emit ExperimentRunUi::renderRestoreList();
    /* 渲染结果曲线 */
    emit ExperimentRunUi::successRenderResultCurve();
}

/* 回传温度时，界面样式设置 */
void ExperimentRunUi::callbackIsTempStyle(QString wenduData){
    ui->labelInfo8->setText(wenduData + "℃");
    ui->temp->setText(wenduData + "℃");
}

/* 渲染当前阶段 */
void ExperimentRunUi::callbackRenderStage(QString stageNo){
    LOG << "stageNo" << stageNo << "stageNo.toInt()" << stageNo.toInt();
    if(stageNo.toInt() != 0){
        switch(stageNo.toInt()){
        case 1: ui->stageName->setText("保温阶段"); break;
        case 2: ui->stageName->setText("PCR阶段"); break;
        case 3: ui->stageName->setText("熔解曲线阶段"); break;
        default: ui->stageName->setText("阶段未识别"); break;
        }
    }
}

/* 发送温度指令。获取回传信息 */
void ExperimentRunUi::callbackGetWenduData(){
    /* 判断是否建立连接 */
    if(!cDevS.instructionsService->m_socketClient->isConnected()){
        cDevS.instructionsService->establishConnection(cDevS.dev.ip, cDevS.dev.port.toInt());
    }
    /* 发送温度指令 */
    cDevS.instructionsService->sendWenduData(cDevS.dev.id, id);
    /* 发送信号：获取并渲染指令 */
    emit ExperimentRunUi::sigRenderZhiLingInfo();
    //    this->sleep(EXPERIMENT_RUNNING_SLEEP_TIME);
}

/* 发送荧光指令。获取回传信息 */
void ExperimentRunUi::callbackGetYingGuangData(){
    /* 判断是否建立连接 */
    if(!cDevS.instructionsService->m_socketClient->isConnected()){
        cDevS.instructionsService->establishConnection(cDevS.dev.ip, cDevS.dev.port.toInt());
    }
    /* 发送荧光指令 */
    cDevS.instructionsService->sendYingguangData(cDevS.dev.id, id);
    /* 发送信号：获取并渲染指令 */
    emit ExperimentRunUi::sigRenderZhiLingInfo();
    LOG << "荧光休眠";
}

/* 发送故障指令 */
void ExperimentRunUi::callbackGetGuzhangData(){
    /* 判断是否建立连接 */
    if(!cDevS.instructionsService->m_socketClient->isConnected()){
        cDevS.instructionsService->establishConnection(cDevS.dev.ip, cDevS.dev.port.toInt());
    }
    cDevS.instructionsService->sendGuzhangData(cDevS.dev.id, id);
    /* 发送信号：获取并渲染指令 */
    emit ExperimentRunUi::sigRenderZhiLingInfo();
}

/* 回传数据，减时间样式设置 */
void ExperimentRunUi::callbackMinusTime(){
    /* 记录前一个步骤的温度 */
    float previousStepTemp = 0;
    /* 记录后一个步骤的温度 */
    float nextStepTemp = 0;

    LOG << "totalRunningTime" << this->totalrunningTime;
    LOG << "this->runningMinute" << this->runningMinute << "this->runningSecond" << this->runningSecond;
    LOG << "this->previousStepTimeAndTemp.size()" << this->previousStepTimeAndTemp.size();

    /* 如果回传有值 */
    if(this->previousStepTimeAndTemp.size() > 0){
        /* 减去已完成步骤时间 */
        this->totalrunningTime = this->totalrunningTime - int(this->previousStepTimeAndTemp[0]);
        /* 记录前一个步骤的温度 */
        previousStepTemp = this->previousStepTimeAndTemp[1];
    }

    LOG << "后一个步骤的阶段和步骤" << this->previousStage << this->previousStep;

    if(this->previousStage != "0000" && this->previousNo != "0000" && this->previousStep != "0000" && this->previousCycling != "0000"){
        /* 获取后一个步骤的时间和温度 */
        this->nextStepTimeAndTemp = procedureService->getStepTimeAndTemperatureByRecieve(id, this->previousStage, this->previousNo, this->previousStep);

        LOG << "this->nextStepTimeAndTemp" << this->nextStepTimeAndTemp;

        /* 如果回传有值 */
        if(this->nextStepTimeAndTemp.size() > 0){
            /* 记录后一个步骤的温度 */
            nextStepTemp = this->nextStepTimeAndTemp[1];
        }

        /* 计算温差，减去相应时间 */
        if(nextStepTemp - previousStepTemp > 10.0){
            /* 升温，时间减去3.2秒 */
            this->totalrunningTime -= 3;
        }else if(nextStepTemp - previousStepTemp < -10.0){
            /* 降温，时间减去5秒 */
            this->totalrunningTime -= 5;
        }
    }

    LOG << "nextStepTemp" << nextStepTemp << "previousStepTemp" << previousStepTemp;

    /* 12.19 渲染时间 */
    this->runningMinute = int(this->totalrunningTime / 60);
    this->runningSecond = this->totalrunningTime - runningMinute*60;

    ui->labelInfo12->setText(QString::number(this->runningMinute) + "分" + QString::number(this->runningSecond) + "秒");
    /* 更新步骤 */
    ui->info_2->setText(ui->labelInfo12->text());
    /* 更新循环数 */
    LOG << "更新循环数";
    if(wenduDataList.size() != 0){
        ui->cyclingNo->setText(convertion->hexToDec(wenduDataList[5].toStdString()));
        ui->stepNo->setText(convertion->hexToDec(wenduDataList[4].toStdString()));
    }

    /* 初始化变量 */
    this->previousStepTimeAndTemp.clear();
    this->nextStepTimeAndTemp.clear();

}

/* 获取已完成的扩增时间 */
void ExperimentRunUi::callbackGetFinishedProcedureTime(){
    LOG << "id" << id;
    LOG << "this->previousStage" << this->previousStage << "this->previousNo" << this->previousNo << "this->previousStep" << this->previousStep;

    LOG << "舰事件";
    this->previousStepTimeAndTemp = procedureService->getStepTimeAndTemperatureByRecieve(id, this->previousStage, this->previousNo, this->previousStep);

    LOG << "this->previousStepTimeAndTemp" << this->previousStepTimeAndTemp;

    LOG << "舰事件完毕";
}

/* 渲染指令信息 */
void ExperimentRunUi::callbackRenderZhiLingInfo(){
    if(cDevS.instructionsService->m_socketClient->isWritten){
        QString zhilingstring = cDevS.instructionsService->m_socketClient->returnZhiLing2Ui();
        /* 渲染指令 */
        ui->textEdit_mistake->append(zhilingstring);
    }
}

/* 渲染未解析指令信息 */
void ExperimentRunUi::callbackRenderNotParseZhilingInfo(){
    if(cDevS.instructionsService->m_socketClient->isNotParseWritten){
        QString notParseZhiling = cDevS.instructionsService->m_socketClient->returnNotParseZhiling2Ui();
        /* 渲染指令 */
        ui->textEdit_mistake->append(notParseZhiling);
        /* 调用解析后的指令 */
    }
    this->callbackRenderZhiLingInfo();
}

/* 获取当实验结束回传0时渲染ui */
void ExperimentRunUi::callbackGetZeroSuccess(){
    /* 时间改为0分0秒 */
    ui->info_2->setText("0分0秒");
    ui->labelInfo12->setText("0分0秒");
    /* 步骤改为最后一步 */
    //    ui->stepNo->setText(QString::number(this->previousStep.toInt()));
    /* 循环数改为最后一个循环数 */
    ui->cyclingNo->setText(QString::number(totalCycling));
}

/* 发送运行时数据 */
QHash<QString, QString> ExperimentRunUi::sendRuntimeData(){
    QHash<QString, QString> runtimeData;
    /* 开始时间 */
    runtimeData.insert("startTime", ui->labelInfo10->text());
    /* 结束时间 */
    runtimeData.insert("endTime", ui->labelInfo4->text());
    if(ui->labelInfo8->text() != ""){
        /* 开始时间 */
        QString wenduNum = ui->labelInfo8->text().split("℃")[0];
        runtimeData.insert("reshiWendu", wenduNum);
    }
    else {
        runtimeData.insert("reshiWendu", ui->labelInfo8->text());
    }

    return runtimeData;
}

/* 反应板鼠标悬停效果 */
void ExperimentRunUi::ShowTooltip(QModelIndex index)
{
    normalIndex = index;
    int count = 8 * index.column() + index.row();
    QList<QLabel*> labels = ui->expRunTable->cellWidget(index.row(), index.column())->findChildren<QLabel*>();

    QString data = "";
    for(int l = 0; l < 20; l ++){
        if(reactionPlate.targetList[count][l].name != "null"){
            data += reactionPlate.targetList[count][l].name;
            data += " ";
        }
    }

    QToolTip::showText(QCursor::pos(), data);

    for(int l = 0 ; l < labels.count(); l ++){
        labels.at(l)->setToolTip(data);
    }
    if(labels.size() != 0){
        /* 容器元素也加上toolTip */
        ui->expRunTable->cellWidget(index.row(), index.column())->setToolTip(data);
    }
}

/* 渲染WLK数据 */
void ExperimentRunUi::renderRunWlkData(QHash<QString, QString> wlkRunData){
    /* 写入其他实验信息 */
    ui->labelInfo10->setText(wlkRunData["startTime"]);
    ui->labelInfo4->setText(wlkRunData["endTime"]);
    ui->labelInfo8->setText(wlkRunData["reshiWendu"] + "℃");

    /* 写入设备信息 */
    ConnectedDeviceStruct tDev;
    tDev.dev.name = wlkRunData["device_name"];
    tDev.dev.id = wlkRunData["device_id"];
    tDev.dev.serial_number = wlkRunData["device_series"];

    this->cDevS = tDev;
}

/* 运行时间函数 */
void ExperimentRunUi::runningTimerCallback(){
    int minute, second;
    /* 获取当前运行时间 */
    QString currentRunningTime = ui->info_4->text();
    /* 拆分为分钟和秒 */
    if(currentRunningTime != ""){
        QStringList minuteList = currentRunningTime.split("分");
        if(minuteList.size() > 1){
            minute = minuteList[0].toInt();
            QStringList secondList = minuteList[1].split("秒");
            if(secondList.size() != 0){
                second = secondList[0].toInt();
            }
        }
    }
    second++; // 秒数增加
    /* 分钟进位 */
    if(second > 59){
        second = 0;
        minute++;
    }
    ui->info_4->setText(QString::number(minute) + "分" + QString::number(second) + "秒");
}

/* 获取反应板靶基因数据，对应曲线图例 */
QHash<QString, QString> ExperimentRunUi::getReactionPlateTarget(){
    qDebug() << "getthis->reactionPlateTarget";

    /* 初始化 */
    targetLegend.clear();
    targetLegendColor1 = "";
    targetLegendColor2 = "";
    targetLegendColor3 = "";
    targetLegendColor4 = "";

    qDebug() << "反应板开始";

    for(int i = 0; i < 96; i++){
        /* 遍历反应孔孔位获取报告基因和对应靶基因名称 */
        QString reporter1 = this->reactionPlate.targetList[i][0].reporter;
        QString reporter2 = this->reactionPlate.targetList[i][1].reporter;
        QString reporter3 = this->reactionPlate.targetList[i][2].reporter;
        QString reporter4 = this->reactionPlate.targetList[i][3].reporter;
        QString name1 = this->reactionPlate.targetList[i][0].name;
        QString name2 = this->reactionPlate.targetList[i][1].name;
        QString name3 = this->reactionPlate.targetList[i][2].name;
        QString name4 = this->reactionPlate.targetList[i][3].name;

        /* 写入报告基因对应靶基因名称 */
        if(reporter1 != "null"){
            if(reporter1 == "FAM" && targetLegend["1"] == ""){
                targetLegend.insert("1", name1);
                targetLegendColor1 = this->reactionPlate.targetList[i][0].color;
                targetReporter1 = reporter1;
            }
            else if(reporter1 == "VIC" && targetLegend["2"] == ""){
                targetLegend.insert("2", name1);
                targetLegendColor2 = this->reactionPlate.targetList[i][0].color;
                targetReporter2 = reporter1;
            }
            else if(reporter1 == "ROX" && targetLegend["3"] == ""){
                targetLegend.insert("3", name1);
                targetLegendColor3 = this->reactionPlate.targetList[i][0].color;
                targetReporter3 = reporter1;
            }
            else if(reporter1 == "CY5" && targetLegend["4"] == ""){
                targetLegend.insert("4", name1);
                targetLegendColor4 = this->reactionPlate.targetList[i][0].color;
                targetReporter4 = reporter1;
            }
        }
        if(reporter2 != "null"){
            if(reporter2 == "FAM" && targetLegend["1"] == ""){
                targetLegend.insert("1", name2);
                targetLegendColor1 = this->reactionPlate.targetList[i][1].color;
                targetReporter1 = reporter2;
            }
            else if(reporter2 == "VIC" && targetLegend["2"] == ""){
                targetLegend.insert("2", name2);
                targetLegendColor2 = this->reactionPlate.targetList[i][1].color;
                targetReporter2 = reporter2;
            }
            else if(reporter2 == "ROX" && targetLegend["3"] == ""){
                targetLegend.insert("3", name2);
                targetLegendColor3 = this->reactionPlate.targetList[i][1].color;
                targetReporter3 = reporter2;
            }
            else if(reporter2 == "CY5" && targetLegend["4"] == ""){
                targetLegend.insert("4", name2);
                targetLegendColor4 = this->reactionPlate.targetList[i][1].color;
                targetReporter4 = reporter2;
            }
        }
        if(reporter3 != "null"){
            if(reporter3 == "FAM" && targetLegend["1"] == ""){
                targetLegend.insert("1", name3);
                targetLegendColor1 = this->reactionPlate.targetList[i][2].color;
                targetReporter1 = reporter3;
            }
            else if(reporter3 == "VIC" && targetLegend["2"] == ""){
                targetLegend.insert("2", name3);
                targetLegendColor2 = this->reactionPlate.targetList[i][2].color;
                targetReporter2 = reporter3;
            }
            else if(reporter3 == "ROX" && targetLegend["3"] == ""){
                targetLegend.insert("3", name3);
                targetLegendColor3 = this->reactionPlate.targetList[i][2].color;
                targetReporter3 = reporter3;
            }
            else if(reporter3 == "CY5" && targetLegend["4"] == ""){
                targetLegend.insert("4", name3);
                targetLegendColor4 = this->reactionPlate.targetList[i][2].color;
                targetReporter4 = reporter3;
            }
        }
        if(reporter4 != "null"){
            if(reporter4 == "FAM" && targetLegend["1"] == ""){
                targetLegend.insert("1", name4);
                targetLegendColor1 = this->reactionPlate.targetList[i][3].color;
                targetReporter1 = reporter4;
            }
            else if(reporter4 == "VIC" && targetLegend["2"] == ""){
                targetLegend.insert("2", name4);
                targetLegendColor2 = this->reactionPlate.targetList[i][3].color;
                targetReporter2 = reporter4;
            }
            else if(reporter4 == "ROX" && targetLegend["3"] == ""){
                targetLegend.insert("3", name4);
                targetLegendColor3 = this->reactionPlate.targetList[i][3].color;
                targetReporter3 = reporter4;
            }
            else if(reporter4 == "CY5" && targetLegend["4"] == ""){
                targetLegend.insert("4", name4);
                targetLegendColor4 = this->reactionPlate.targetList[i][3].color;
                targetReporter4 = reporter4;
            }
        }

        /* 如果QHash四个孔位都不为空，提前退出循环 */
        if(targetLegend["1"] != "" && targetLegend["2"] != "" && targetLegend["3"] != "" && targetLegend["4"] != "")
            break;
    }


    qDebug() << "反应板结束";

    /* 更换图例名称、渲染曲线和图例颜色 */
    // FAM
    if(targetLegend["1"] != ""){
        ui->famLabel->show();
        ui->famBtn->show();
        ui->famLabel->setText(targetLegend["1"] + "("+ targetReporter1 + ")");
        QString styleSheet = "QPushButton {min-width: 10px; max-width: 10px; min-height: 10px; max-height: 10px; border: 1px solid rgba(0,0,0,.5);" "background-color: rgb(" + targetLegendColor1 + ");}";
        ui->famBtn->setStyleSheet(styleSheet);

    }
    else{
        ui->famLabel->hide();
        ui->famBtn->hide();
    }
    // VIC
    if(targetLegend["2"] != ""){
        ui->vicLabel->show();
        ui->vicBtn->show();
        ui->vicLabel->setText(targetLegend["2"] + "("+ targetReporter2 + ")");
        QString styleSheet = "QPushButton {min-width: 10px; max-width: 10px; min-height: 10px; max-height: 10px; border: 1px solid rgba(0,0,0,.5);" "background-color: rgb(" + targetLegendColor2 + ");}";
        ui->vicBtn->setStyleSheet(styleSheet);
    }
    else{
        ui->vicLabel->hide();
        ui->vicBtn->hide();
    }
    // ROX
    if(targetLegend["3"] != ""){
        ui->roxLabel->show();
        ui->roxBtn->show();
        ui->roxLabel->setText(targetLegend["3"] + "("+ targetReporter3 + ")");
        QString styleSheet = "QPushButton {min-width: 10px; max-width: 10px; min-height: 10px; max-height: 10px; border: 1px solid rgba(0,0,0,.5);" "background-color: rgb(" + targetLegendColor3 + ");}";
        ui->roxBtn->setStyleSheet(styleSheet);
    }
    else{
        ui->roxLabel->hide();
        ui->roxBtn->hide();
    }

    // CY5
    if(targetLegend["4"] != ""){
        ui->cy5Label->show();
        ui->cy5Btn->show();
        ui->cy5Label->setText(targetLegend["4"] + "("+ targetReporter4 + ")");
        QString styleSheet = "QPushButton {min-width: 10px; max-width: 10px; min-height: 10px; max-height: 10px; border: 1px solid rgba(0,0,0,.5);" "background-color: rgb(" + targetLegendColor4 + ");}";
        ui->cy5Btn->setStyleSheet(styleSheet);
    }
    else{
        ui->cy5Label->hide();
        ui->cy5Btn->hide();
    }

    /* 设置曲线颜色 */
    for(int i = 0; i < 96; i++){
        if(targetLegendColor1 != ""){
            QStringList tarColor1 = targetLegendColor1.split(",");
            famSeriesList[i]->setPen(QPen(QColor(tarColor1[0].toInt(), tarColor1[1].toInt(), tarColor1[2].toInt(), 255),2,Qt::SolidLine)); //设置画笔
            famSeriesList[i]->setColor(QColor(tarColor1[0].toInt(), tarColor1[1].toInt(), tarColor1[2].toInt(), 255));  //设置颜色
        }
        else {
            famSeriesList[i]->setPen(QPen(QColor(0,0,0,0),2,Qt::SolidLine)); //设置画笔
            famSeriesList[i]->setColor(QColor(0,0,0,0));  //设置颜色
        }
        if(targetLegendColor2 != ""){
            QStringList tarColor2 = targetLegendColor2.split(",");
            vicSeriesList[i]->setPen(QPen(QColor(tarColor2[0].toInt(), tarColor2[1].toInt(), tarColor2[2].toInt(), 255),2,Qt::SolidLine)); //设置画笔
            vicSeriesList[i]->setColor(QColor(tarColor2[0].toInt(), tarColor2[1].toInt(), tarColor2[2].toInt(), 255));  //设置颜色
        }
        else {
            vicSeriesList[i]->setPen(QPen(QColor(0,0,0,0),2,Qt::SolidLine)); //设置画笔
            vicSeriesList[i]->setColor(QColor(0,0,0,0));  //设置颜色
        }
        if(targetLegendColor3 != ""){
            QStringList tarColor3 = targetLegendColor3.split(",");
            roxSeriesList[i]->setPen(QPen(QColor(tarColor3[0].toInt(), tarColor3[1].toInt(), tarColor3[2].toInt(), 255),2,Qt::SolidLine)); //设置画笔
            roxSeriesList[i]->setColor(QColor(tarColor3[0].toInt(), tarColor3[1].toInt(), tarColor3[2].toInt(), 255));  //设置颜色
        }
        else {
            roxSeriesList[i]->setPen(QPen(QColor(0,0,0,0),2,Qt::SolidLine)); //设置画笔
            roxSeriesList[i]->setColor(QColor(0,0,0,0));  //设置颜色
        }
        if(targetLegendColor4 != ""){
            QStringList tarColor4 = targetLegendColor4.split(",");
            cy5SeriesList[i]->setPen(QPen(QColor(tarColor4[0].toInt(), tarColor4[1].toInt(), tarColor4[2].toInt(), 255),2,Qt::SolidLine)); //设置画笔
            cy5SeriesList[i]->setColor(QColor(tarColor4[0].toInt(), tarColor4[1].toInt(), tarColor4[2].toInt(), 255));  //设置颜色
        }
        else {
            cy5SeriesList[i]->setPen(QPen(QColor(0,0,0,0),2,Qt::SolidLine)); //设置画笔
            cy5SeriesList[i]->setColor(QColor(0,0,0,0));  //设置颜色
        }
    }

    return targetLegend;
}

void ExperimentRunUi::updateTable(){
    for(int i = 0; i < 8; i ++){
        for(int j = 0; j < 12; j ++){
            QVBoxLayout* vLayout = new QVBoxLayout();
            QWidget* widgetLabel = new QWidget();
            QGridLayout* gLayout = new QGridLayout();
            widgetLabel->setLayout(vLayout);

            int count = 8 * j + i;
            if(ui->toolButton->menu()->actions().value(0)->toolTip() == "样本名称" && ui->toolButton->menu()->actions().value(0)->isChecked() == true && ui->toolButton->menu()->actions().value(2)->isChecked() == true){
                QString strname = reactionPlate.sampleList[count].name;
                if(strname != "null"){
                    QLabel *label = new QLabel();
                    QColor color = stringToColor(reactionPlate.sampleList[count].color_value);
                    QRgb rgbColor = qRgb(color.red(), color.green(), color.blue());
                    QString mRgbStr = QString::number(rgbColor, 16);
                    widgetLabel->setStyleSheet("background-color: #" + mRgbStr);
                    label->setText(strname);
                    QFont font;
                    font.setFamily("Alibaba PuHuiTi");
                    font.setPointSize(5);
                    label->setAlignment(Qt::AlignHCenter);
                    label->setFont(font);
                    label->setFixedHeight(16);
                    vLayout->addWidget(label);
                }
            }
            if(ui->toolButton->menu()->actions().value(0)->toolTip() == "样本名称" && ui->toolButton->menu()->actions().value(0)->isChecked() == true && ui->toolButton->menu()->actions().value(2)->isChecked() == false){
                QString name = reactionPlate.sampleList[count].name;
                if(name != "null"){
                    QLabel *label = new QLabel();
                    label->setText(name);
                    QFont font;
                    font.setFamily("Alibaba PuHuiTi");
                    font.setPointSize(5);
                    label->setFont(font);
                    label->setAlignment(Qt::AlignHCenter);
                    label->setFixedHeight(16);
                    vLayout->addWidget(label);
                }
            }
            if(ui->toolButton->menu()->actions().value(0)->toolTip() == "样本名称" && ui->toolButton->menu()->actions().value(0)->isChecked() == false && ui->toolButton->menu()->actions().value(2)->isChecked() == true){
                QString name = reactionPlate.sampleList[count].name;
                if(name != "null"){
                    QLabel *label = new QLabel();
                    QColor color = stringToColor(reactionPlate.sampleList[count].color_value);
                    QRgb rgbColor = qRgb(color.red(), color.green(), color.blue());
                    QString mRgbStr = QString::number(rgbColor, 16);
                    widgetLabel->setStyleSheet("background-color: #" + mRgbStr);
                    vLayout->addWidget(label);
                }
            }

            int p = 0;
            for(int l = 0; l < 20; l ++){
                if(ui->toolButton->menu()->actions().value(1)->toolTip() == "靶基因" && ui->toolButton->menu()->actions().value(1)->isChecked() == true){
                    if(reactionPlate.targetList[count][l].reporter != "null"){
                        QString reporter = reactionPlate.targetList[count][l].type;
                        if(reporter.contains("unknown(未知)")
                                || reporter.contains("Unknown(未知)")
                                || reporter.contains("未知")){reporter = "U " + reactionPlate.targetList[count][l].reporter;}
                        if(reporter.contains("stander(标准)")
                                || reporter.contains("Stander(标准)")
                                || reporter.contains("标准")){reporter = "S " + reactionPlate.targetList[count][l].reporter;}
                        if(reporter == "NTC"){reporter = "N " + reactionPlate.targetList[count][l].reporter;}
                        QLabel *label = new QLabel();
                        QColor color = stringToColor(reactionPlate.targetList[count][l].color);
                        QRgb rgbColor = qRgb(color.red(), color.green(), color.blue());
                        QString mRgbStr = QString::number(rgbColor, 16);
                        label->setText(reporter);
                        QFont font;
                        font.setFamily("Alibaba PuHuiTi");
                        font.setPointSize(5);
                        label->setFont(font);
                        label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
                        label->setStyleSheet("QLabel{border:2px solid #" + mRgbStr +";}");
                        //                        label->setFixedSize(55, 20);
                        label->resize(static_cast<int>(strlen(reinterpret_cast<char*>(label->text().data()))) * label->font().pointSize(),20);label->setFixedHeight(18);
                        gLayout->addWidget(label, p / 10, p % 10, Qt::AlignCenter);
                        p ++;
                    }
                }
            }
            vLayout->addLayout(gLayout);
            vLayout->setSpacing(0);
            vLayout->setMargin(0);
            ui->expRunTable->setCellWidget(i, j, widgetLabel);
        }

    }
}

QColor ExperimentRunUi::stringToColor(QString colorStr)
{
    QColor color;
    QStringList rgb=colorStr.split(',');
    if(rgb.size()==3){
        int r=rgb.at(0).toInt();
        int g=rgb.at(1).toInt();
        int b=rgb.at(2).toInt();
        color.setRgb(r,g,b);
    }
    else
        color.setNamedColor(colorStr);

    return color;
}

/* 判断反应板数据是否为空 */
bool ExperimentRunUi::reactionPlateDataIsEmpty(){
    LOG << "reactionPlate.targetList" << reactionPlate.targetList[0][0].reporter;

    /* 遍历反应板数据 */
    for(int i = 0; i < 96; i++){
        if(this->reactionPlate.targetList[i][0].name != "null")
            return false;
        if(this->reactionPlate.targetList[i][1].name != "null")
            return false;
        if(this->reactionPlate.targetList[i][2].name != "null")
            return false;
        if(this->reactionPlate.targetList[i][3].name != "null")
            return false;
    }
    return true;
}

/* 所有组件失效 */
void ExperimentRunUi::allComponentsInvalid(){
    ui->runningDevice->setEnabled(false);
    ui->startBtn->setEnabled(false);
    ui->startBtn->setStyleSheet(
                "font-family: 'Alibaba PuHuiTi';"
                "color: #fff;"
                "font-size: 18px;"
                "font-weight: bold;"
                "border-radius: 8px;"
                "background-color: #a2a2a2;");
}

/* 所有组件生效 */
void ExperimentRunUi::allComponentsValid(){
    ui->runningDevice->setEnabled(true);
    ui->startBtn->setEnabled(true);
    ui->startBtn->setStyleSheet(
                "font-family: 'Alibaba PuHuiTi';"
                "color: #fff;"
                "font-size: 18px;"
                "font-weight: bold;"
                "border-radius: 8px;"
                "background-color: rgb(0,170,127);");
}

/* 休眠函数 */
void ExperimentRunUi::sleep(int msec){
    QTime dieTime = QTime::currentTime().addMSecs(msec);
    while( QTime::currentTime() < dieTime)
        QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
}
